深入了解linux系統—— 基礎IO(上)

文件

在之前學習C語言文件操作時,我們了解過什么是文件,這里簡單回顧一下:

文件存在磁盤中,文件有分為程序文件、數據文件;二進制文件和文本文件等。

詳細描述見文章:文件操作——C語言

  • 文件在磁盤里,磁盤是永久性存儲介質,因為文件在磁盤上的存儲是永久性的;
  • 磁盤是外設(是輸入設備也是輸出設備);
  • 本質上對磁盤是文件的所有操作,都是對外設的輸入和輸出;也就是I/O

對于文件的認識:

  • 文件 = 文件內容 + 文件屬性
  • 文件大小是0KB的文件也是占用磁盤空間的
  • 所有對于文件的相關操作都是對文件內容和文件屬性就行操作。

在系統層面理解

  • 我們操作文件(打開,關閉文件),本質上是進程對于文件的操作;
  • 磁盤的管理者是操作系統;
  • 我們在C/C++使用庫函數來對文件進行讀寫操作,本質上是通過文件相關的系統調用去完成的。

C文件操作

打開和關閉文件

C語言當中,我們通過fopen來打開文件,fclose來關閉文件;

  1. fopen:打開文件,如果打開成功返回一個FILE*類型的指針,執行被打開的文件;打開失敗則返回NULL
  2. fclose:關閉文件,傳參FILE*類型的指針,關閉指定文件。
#include <stdio.h>
int main()      
{      FILE* fp = fopen("log.txt","w");//以讀方式打開,文件不存在就新建      if(fp == NULL){      perror("fopen");      return 1;      }      //....      fclose(fp);//關閉文件                                                              return 0;                                             
}  

打開文件的方式

在這里插入圖片描述

我們知道在C語言的fopen接口打開文件是有很多打開方式

r:以讀方式打開、w以寫方式打開、a以追加方式打開。

r方式,當文件不存在時就打開文件失敗;

w方式,當文件不存在時就新建文件(在當前工作路徑下創建,進程當中存放了當前工作路徑);如果文件存在會清空當前文件的內容;然后在進入寫入。

a方式,追加,當文件不存在就新建文件;如果文件已經存在,打開時不會清空文件內容,而是在文件末尾進行寫入

寫文件

當我們以w/r方式打開一個文件,我們要將內容寫到文件當中;

img

我們可以使用fputcfputsfwritefprintf進行文件的寫入;

#include <stdio.h>
int main()      
{      FILE* fp = fopen("log.txt","w");//以讀方式打開,文件不存在就新建      if(fp == NULL){      perror("fopen");      return 1;      }      for(char ch = 'a';ch <= 'z';ch++){    fputc(ch,fp);    }    char* str = (char*)"I love you\n";    fputs(str,fp);    int x = 100;    fprintf(fp,"x = %d\n",x); fclose(fp);//關閉文件                                                              return 0;                                             
}  

在這里插入圖片描述

文件讀取

我們以r方式打開一個文件,我們要像讀取這個文件的內容,我們可以使用fgetcfgetsfscanf進入文件內容的讀取操作:

#include <stdio.h>
int main()      
{      FILE* fp = fopen("log.txt","w");//以讀方式打開,文件不存在就新建      if(fp == NULL){      perror("fopen");      return 1;      }for(int i = 0;i<26;i++){    printf("%c",fgetc(fp));    }    printf("\n");    char buff[20];    fgets(buff,12,fp);    //buff[11] = '\0';    printf("%s",buff);    int x;    fscanf(fp,"x = %d",&x);    printf("x = %d\n", x);  fclose(fp);//關閉文件                                                              return 0;                                 
}  

在這里插入圖片描述

stdin/stdout/stderr

在我們程序運行時,C語言它會默認打開三個文件:stdinstdoutstderr

我們可以發現這三個都是文件類型指針

在這里插入圖片描述

系統文件I/O

在上述C語言的文件操作fopenfclose都是語言層提供給我們的文件操作接口;以及C語言的stdinstdoutstderr;C++中的cincoutcerr都是語言層提供給我們的方案;

我們知道文件的管理者是操作系統,所以我們對文件操作都要經過操作系統;

那也就是說語言層的文件操作接口,其底層都封裝了系統調用。

1. 傳遞多個標志位的方法

在之前的習慣中,我們通常使用一個參數來作為一個標記位;這樣我們在傳遞多個標志位時就需要傳遞多個參數。

現在來了解一種使用一個參數來傳遞多個標志位的方法:

使用一個bit為來作為一個標識符,這樣使用一個參數就可以表示多個標志位了。

#include <stdio.h>
#define ONE 0001   //0000 0001
#define TWO 0002   //0000 0010
#define THREE 0004 //0000 0100   
void func(int flag){    if(flag & ONE)  printf("ONE ");    if(flag & TWO)  printf("TWO ");    if(flag & THREE)  printf("THREE ");    printf("\n");    
}    
int main()    
{    func(ONE);    func(ONE | TWO);    func(ONE | THREE);    func(ONE | TWO | THREE);  return 0;
}

在這里插入圖片描述

這樣就可以使用一個參數,傳遞多個標志位了。

Linux操作系統open接口就使用了一個參數來傳遞多個標志位。

2. 打開文件open

在語言層面,我們使用的fopen,它本質上就是對系統調用的封裝;

在這里插入圖片描述

可以看到open是一個系統調用;它的作用就是打開一個文件,也可能會創建一個新的文件。

我們可以看到open函數它存在一個兩個參數的,也存在一個三個參數的;

  1. pathname:表示要打開文件的文件名(不帶路徑就默認在當前工作路徑下)
  2. flags:表示文件的打開方式,存在多個標志位
  3. mode:表示新建文件時,文件的默認權限

文件名pathname

這個想必就不用多說了,表示要打開文件的文件名;

不帶路徑時,就表示在當前工作路徑下打開文件。(進程中存在當前工作路徑cwd

標志位flags

通過查看open函數說明可以看到,flags存在非常多的標志位;這里列舉一些常用的選項

O_RDONLY只讀、O_WRONLY只寫、O_RDWR讀寫;

O_CREAT:文件不存在時就新建文件

O_TRUNC:打開文件時,文件存在就清空文件內容

O_APPEND:打開文件時,以追加形式打開。

這里flags表示的就是文件的打開方式;

首先就是:只讀、只寫和讀寫;在我們打開文件時必須指定一個且只能指定一個。

O_CREAT

在我們打開一個文件時,如果這個文件不存在,那open函數就會直接返回-1表示文件打開失敗;

而我們帶了O_CREAT選項,就表明當文件不存在時,就新建文件;(這里新建文件要指明新建文件的權限,否則創建出來文件的權限就是亂碼

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd = open("love.txt",O_CREAT | O_WRONLY,0666);      if(fd < 0){      perror("open");      return 1;                                                                                                 }                                                                                                            return 0;                                                                                                    
}    

在這里插入圖片描述

一般情況下,在以寫方式打開文件,文件不存在就新建,就要指明文件的權限。

(以只讀讀方式O_RDONLY,文件不存在新建出的文件是空的,沒有什么意義)

O_TRUNC

當我們打開一個文件時,如果這個文件已經存在了,那就打開這個已有的文件;

如果我們帶了O_TRUNC選項,就表示清空這個文件的內容;

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd = open("love.txt",O_CREAT | O_WRONLY | O_TRUNC,0666);      if(fd < 0){      perror("open");      return 1;                                                                                                 }                                                                                                            return 0;                                                                                                    
}

在這里插入圖片描述

O_APPEND

在C語言的文件操作中,fopen打開文件,w就是以寫方式打開、文件不存在就新建、文件存在就清空文件的內容;(這就對應了上述選項的O_WRONLYO_CREATO_TRUNC

但是我們fopen還可以以a方式打開文件,也就是追加方式;這里的O_APPEND就是以追加的方式打開文件。

這里我們先看一種現象:

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd = open("love.txt",O_CREAT | O_WRONLY,0666);      if(fd < 0){      perror("open");      return 1;                                                                                                 }char buff[] = "abcdef";write(fd,buff,strlen(buff));  return 0;                                                                                                    
}

在這里插入圖片描述

可以看到,我們不帶O_APPEND選項,寫入的時候是在文件的開頭位置進行寫入的。

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd = open("love.txt",O_CREAT | O_WRONLY | O_APPEND,0666);      if(fd < 0){      perror("open");      return 1;                                                                                                 }char buff[] = "abcdef";write(fd,buff,strlen(buff));  return 0;                                                                                                    
}

在這里插入圖片描述

文件權限mode

當打開文件,文件不存在,我們還帶了O_CREAT選項時;如果我們不帶文件的權限,那新建文件的權限就是亂碼;

而新建的文件的權限:文件權限 = 默認權限 &(~umask)

3. 關閉文件

關閉文件的系統調用close,根據文件描述符,關閉指定文件。

在這里插入圖片描述

對于這里的fd,它指的是文件描述符,當我們打開文件成功時,會返回給我們該文件的文件描述符;

我們對指定文件的讀寫操作,以及關閉文件都要使用指定文件的文件描述符。

4. 文件寫入write

在C語言中,我們進行文件寫入時,我們有非常多的接口;

但是在系統層面,我們對文件進行寫入只有一個接口,就是write

在這里插入圖片描述

write有三個參數,分別是fdbuf、和count

其中fd指的是文件描述符,表示我們要向哪一個文件進行寫入;

buf表示我們要進行寫入的內容,它是void*類型的指針,可以寫入任何數據

count就表示,我們要寫入內容的長度。

這里值的注意的是:這里write主要用于字符寫入

當然,我們之前聽過文本寫入和二進制寫入,那都是語言層的概念;

再這里我們操作系統不管這些,write就將給定的內容寫入到文件緩沖區中。

5. 文件讀取read

和寫入一樣,在語言層我們有非常多的函數接口,但是在系統層面,就只有read

在這里插入圖片描述

這樣存在三個參數;

fd文件描述符,表示要從哪一個文件讀取數據;

buf,表示我們要將文件中的數據讀取到buf中;

count表示要讀取內容的長度。

文件描述符

在上面描述中,我們了解了文件操作相關的系統調用;

openwritereadclose這些系統調用中,都用到了一個fd來指明一個文件;那這個fd究竟是什么呢?

open函數的返回值

在上述使用open函數時,我們并沒有關心open函數的返回值,也沒有說明文件描述符到底是什么?

在這里插入圖片描述

當我們使用open打開一個文件時:

如果打開成功,那就返回這個新打開文件的文件描述符;

如果打開失敗,就返回-1,并且設置錯誤碼。

什么是文件描述符

那我們知道了,文件描述符就是標識一個文件的整數,每一個文件的文件描述符都不一樣;

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd = open("log.txt",O_CREAT | O_WRONLY | O_APPEND,0666);if(fd < 0)	return -1;printf("fd : %d\n",fd);close(fd);return 0;                                                                                                    
}

在這里插入圖片描述

我們可以看到打開的一個文件的文件描述符是3

這里打開一個文件我們看不出來什么,我們多打開一些文件

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>
int main()      
{      int fd1 = open("log1.txt",O_CREAT | O_WRONLY | O_APPEND,0666);int fd2 = open("log2.txt",O_CREAT | O_WRONLY | O_APPEND,0666);int fd3 = open("log3.txt",O_CREAT | O_WRONLY | O_APPEND,0666);int fd4 = open("log4.txt",O_CREAT | O_WRONLY | O_APPEND,0666);//這里就不做錯誤判斷了printf("fd1 : %d\n",fd1);printf("fd2 : %d\n",fd2);printf("fd3 : %d\n",fd3);printf("fd4 : %d\n",fd4);//不關閉文件,進程結束會自動關閉return 0;                                                                                                    
}

在這里插入圖片描述

這里,我們可以發現我們打開多個文件,這些文件的文件描述符是線性增長的。

文件描述符0/1/2

在上述中,我們發現,我們的文件描述符它是線性增長的,而且我們打開第一個文件它的文件描述符是3

012文件描述符去哪里了呢?

還記得在程序運行時,C語言會默認給我們打開三個文件stdinstdoutstrerr

Linux操作系統中,進程默認情況下會有三個缺省打開的文件描述符(012),分別是標準輸入、標準輸出和標準錯誤。

那這里進程默認打開的標準輸入、標準輸出和標準錯誤和C語言中的stdinstdoutstderr有什么區別呢?

這里0標準輸入、1標準輸出、2標準錯誤;

一般情況下0,1,2對應的物理設備是鍵盤、顯示器、顯示器。

所以,我們從鍵盤中讀取數據就是從0文件中讀取數據;將數據輸出到顯示器中就是將數據輸出到1文件當中。

文件描述符的分配規則

當我們打開一個文件時,它的文件描述符是3;我們打開多個文件時,我們可以發現它的文件描述符是線性增長的;

那文件描述符是如何分配的呢?是一直在增長的嗎?

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>      
#include <unistd.h>      
#include <string.h>      
int main()          
{       int fd1 = open("log1.txt",O_CREAT | O_WRONLY | O_TRUNC, 0666 );    if(fd1 < 0)  return -1;    printf("fd1 : %d\n",fd1);    close(0);    close(2);    int fd2 = open("log2.txt",O_CREAT | O_WRONLY | O_TRUNC, 0666 );    if(fd2 < 0)  return -1;    printf("fd2 : %d\n",fd2);    int fd3 = open("log3.txt",O_CREAT | O_WRONLY | O_TRUNC, 0666 );    if(fd3 < 0)  return -1;    printf("fd3 : %d\n",fd3);return 0;           
}  

在這里插入圖片描述

可以看到,我們關閉02文件之后,新打開文件的文件描述符是02

在這里插入圖片描述

所以,這里我們文件描述符分配時,會從0開始去找到一個最小且沒有被使用的文件描述符,再進行分配。

操作系統對于打開的文件的管理

對于上面的文件描述符,可以說很抽象,為什么可以使用一個整數來表示一個打開的文件呢?

現在來看操作系統是如何對被打開的文件進行管理的。

要想進行管理,那一定是先描述,再組織

**先描述:**操作系統要像對被打開文件進行管理,那就要先描述這些被打開文件;在Linux操作系統中就存在struct file結構體來描述這些被打開的文件(struct file里就可能有文件描述符等等一些關于文件的信息)。

所以,在打開一個文件時,就只需根據文件的相關屬性構建相對應的struct file即可(還存在文件緩沖區,也會將部分內容拷貝到文件緩沖區中

再組織: 操作系統要將這些被打開文件(struct file)進行管理;在Linux操作系統中就存在一個全局鏈表,所以被打開文件的struct file都在這個鏈表當中。

這樣操作系統就將所有被打開的文件管理起來的,但是現在還有一個問題,程序打開文件也就是進程要打開文件,那進程是如何打開的呢?

這個問題就比較簡單了,我們的進程不是有對應的task_struct嗎,那我們進程打開了哪些文件就肯定在tasj_struct中存儲著相對應的信息。

task_struct中,存在著一個指針struct file_struct* files,這個指針指向進程相對應的文件描述符表

而在文件描述符表中,存在著一個數組struct file* fd_array

而我們的文件描述符就和這個fd_array數組的下標一一對應。

那么,也就是說我們文件描述符表在的fd_array數組,下標01…和我們文件描述符一一對應。

那么,在進程執行的過程中,只需要訪問task_struct中的文件描述符表中的fd_array數組,就可以知道我們進程打開了哪些文件。

在這里插入圖片描述

了解了操作系統對于被打開文件的管理,現在再來看文件描述符

它就是進程文件描述符表中fd_array的數組下標;

在新建文件時,操作系統就會遍歷進程的描述符表中fd_array數組,找到一個最小且沒有被使用的數組下標來作為新打開文件的文件描述符。

stdin/stdout/stderr和文件描述符0/1/2的區別

我們知道,在C語言程序啟動時,它會默認打開三個文件stdin/stdout/stderr,這是語言層面的概念;

而文件描述符0/1/2這是操作系統層面的概念。

在C語言中stdin/stdout/stderr的類型都是FILE*,我們只知道FILE*是文件類型的指針,但是FILE它是什么呢?

其他的我們不懂,但是這里我們可以肯定在FILE中肯定存在文件對應的文件描述符;(因為C語言文件操作是封裝了系統調用,而系統調用是使用文件描述符來訪問文件的,所以在FILE肯定存在文件所對應的文件描述符)

并且我們也可以確定,stdin對應的文件描述符肯定是0stdout對應的文件描述符肯定是1stderr對應的文件描述符肯定是2

這里提出一個問題?

我們知道文件描述符的分配規則是找一個最小且沒有被使用的文件描述符進行分配。

那如果我們關閉了0/1/2文件,再創建文件那0/1/2還是標準輸入、標準輸出和標準錯誤嗎?

答案是的,在語言層我們標準輸入stdin中的文件描述符就是0、標準輸出stdout中的文件描述符就是1、標準錯誤stderr中的文件描述符就是2

我們關閉0/1/2文件,這一操作是系統層的操作,我們語言層C它并不知道;

那也就是說,在程序往標準輸出中輸出數據時,它只會拿著stdout中的文件描述符1去調用系統調用;

那也就是說在系統層:文件描述符0指向哪個文件,哪個文件就是標準輸入;文件描述符1指向哪個文件,哪個文件就是標準輸出;文件描述符2指向哪個文件,哪個文件就是標準錯誤。

本篇文章到這里就結束了,感謝各位的支持。
繼續加油!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/81365.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81365.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81365.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flink CDC—實時數據集成框架

Flink CDC 是一個基于流的數據集成工具&#xff0c;旨在為用戶提供一套功能更加全面的編程接口&#xff08;API&#xff09;&#xff0c;它基于數據庫日志的 CDC&#xff08;變更數據捕獲&#xff09;技術實現了統一的增量和全量數據讀取。 該工具使得用戶能夠以 YAML 配置文件…

ES(ES2023/ES14)最新更新內容,及如何減少內耗

截至2023年10月,JavaScript(ECMAScript)的最新版本是 ES2023(ES14)。 ES2023 引入了許多新特性,如findLast、toSorted等,同時優化了性能。通過減少全局變量、避免內存泄漏、優化循環、減少DOM操作、使用Web Workers、懶加載、緩存、高效數據結構和代碼壓縮,可以顯著降低…

常見的 Python 環境配置問題及解決方案

1. Python 環境配置的常見問題 初學者在配置 Python 環境時&#xff0c;可能會遇到以下幾類問題&#xff1a; 1.1 不同版本的兼容性 Python 目前有兩個主要版本系列&#xff1a;Python 2.x 和 Python 3.x。Python 2.x 已于 2020 年 1 月 1 日停止維護&#xff0c;因此強烈建…

day20-線性表(鏈表II)

一、調試器 1.1 gdb&#xff08;調試器&#xff09; 在程序指定位置停頓 1.1.1 一般調試 gcc直接編譯生成的是發布版&#xff08;Release&#xff09; gcc -g //-g調式版本&#xff0c;&#xff08;體積大&#xff0c;內部有源碼&#xff09;&#xff08;DeBug&#…

基于Spring Boot+Layui構建企業級電子招投標系統實戰指南

一、引言&#xff1a;重塑招投標管理新范式 在數字經濟浪潮下&#xff0c;傳統招投標模式面臨效率低、透明度不足、流程冗長等痛點。本文將以Spring Boot技術生態為核心&#xff0c;融合Mybatis持久層框架、Redis高性能緩存及Layui前端解決方案&#xff0c;構建一個覆蓋招標代理…

uniapp -- uCharts 儀表盤刻度顯示 0.9999999 這樣的值問題處理。

文章目錄 ??問題??解決方案??問題 在儀表盤上,23.8變成了 23.799999999999997 ??解決方案 formatter格式化問題 1:在 config-ucharts.js 或 config-echarts.js 配置對應的 formatter 方法 formatter: {yAxisDemo1: function (

git 對于已經追蹤,但沒有git add 的文件,撤回修改的方法

要撤銷對已追蹤文件的修改&#xff08;但尚未使用git add添加到暫存區&#xff09;&#xff0c;你可以使用以下幾種方法&#xff1a; 1. 使用 git restore (Git 2.23.0及更高版本) 這是較新版本Git中推薦的方式&#xff1a; # 撤銷單個文件的修改git restore <file># …

腳本語言Lua

本文來源 &#xff1a;騰訊元寶 Lua是一種輕量級、可嵌入的腳本語言&#xff0c;由巴西里約熱內盧天主教大學的Roberto Ierusalimschy、Waldemar Celes和Luiz Henrique de Figueiredo于1993年開發。其設計目標是嵌入應用程序中&#xff0c;提供靈活的擴展和定制功能。 主要特性…

ThingsBoard使用Cassandra部署時性能優化

1、概述 當遇到ThingsBoard設備數量特別多的時候,并且傳輸數據遙測點量特別大的時候,我們需要調整一下參數來進行優化,使其性能達到最佳的進行快速寫入。 注意:以下這些參數再系統部署的時候就需要規劃好配置,不能安裝好了再二次來進行配置。 2、Cassandra配置參數優化 …

Git Worktree 使用

新入職了一家公司&#xff0c;發現不同項目用的使用一個 git 倉庫管理。不久之后我看到這篇文章。 Git 的設計部??分是為了支持實驗。一旦你確定你的工作被安全地跟蹤&#xff0c;并且存在安全的狀態&#xff0c;以便在出現嚴重錯誤時可以恢復&#xff0c;你就不會害怕嘗試新…

維智定位 Android 定位 SDK

概述 維智 Android 定位 SDK是為 Android 移動端應用提供的一套簡單易用的定位服務接口&#xff0c;為廣大開發者提供融合定位服務。通過使用維智定位SDK&#xff0c;開發者可以輕松為應用程序實現極速、智能、精準、高效的定位功能。 重要&#xff1a;為了進一步加強對最終用…

【CSS】使用 CSS 繪制三角形

一、Border 邊框法&#xff08;最常用&#xff09; 原理&#xff1a;通過設置元素的寬高為 0&#xff0c;利用透明邊框相交形成三角形。 .triangle {width: 0;height: 0;border-left: 50px solid transparent; /* 左側邊框透明 */border-right: 50px solid transparent; /* …

RabbitMQ 快速上手:安裝配置與 HelloWorld 實踐(一)

一、引言 在當今分布式系統大行其道的技術浪潮下&#xff0c;各個服務之間的通信與協同變得愈發復雜。想象一下&#xff0c;一個電商系統在大促期間&#xff0c;訂單服務、庫存服務、支付服務、物流服務等眾多模塊需要緊密配合。如果沒有一種高效的通信機制&#xff0c;系統很容…

【deekseek】TCP Offload Engine

是的&#xff0c;TOE&#xff08;TCP Offload Engine&#xff09;通過專用硬件電路&#xff08;如ASIC或FPGA&#xff09;完整實現了TCP/IP協議棧&#xff0c;將原本由CPU軟件處理的協議計算任務完全轉移到網卡硬件中。其延遲極低的核心原因在于 硬件并行性、零拷貝架構 和 繞過…

JavaScript 的編譯與執行原理

文章目錄 前言&#x1f9e0; 一、JavaScript 編譯與執行過程1. 編譯階段&#xff08;發生在代碼執行前&#xff09;? 1.1 詞法分析&#xff08;Lexical Analysis&#xff09;? 1.2 語法分析&#xff08;Parsing&#xff09;? 1.3 語義分析與生成執行上下文 &#x1f9f0; 二…

WORD個人簡歷單頁326款模版分享下載

WORD個人簡歷模版下載&#xff1a;WORD個人簡歷模版https://pan.quark.cn/s/7e79a822c490

Android 中 顯示 PDF 文件內容(AndroidPdfViewer 庫)

PDFView 是一個用于在 Android 應用中顯示 PDF 文檔的庫。它提供了豐富的功能和靈活的配置選項&#xff0c;使得開發者能夠輕松地在應用中嵌入 PDF 閱讀器。 一、 添加依賴 在模塊的 build.gradle 文件中添加以下依賴&#xff1a; // pdfimplementation("com.github.bar…

微信小程序學習之搜索框

1、第一步&#xff0c;我們在index.json中引入vant中的搜索框控件&#xff1a; {"usingComponents": {"van-search": "vant/weapp/search/index"} } 2、第二步&#xff0c;直接在index.wxml中添加布局&#xff1a; <view class"index…

OpenCL C++ 常見屬性與函數

核心對象與屬性 對象/屬性描述示例cl::Platform表示OpenCL平臺cl::Platform::get(&platforms)cl::Device表示計算設備cl::Device::getDefault()cl::Context管理設備、內存和命令隊列的上下文cl::Context(contextDevices)cl::CommandQueue命令隊列,用于提交命令cl::Command…

Milvus 視角看重排序模型(Rerankers)

在信息檢索和生成式人工智能領域&#xff0c;重排序器是優化初始搜索結果順序的重要工具。重排序器與傳統的嵌入模型不同&#xff0c;它將查詢和文檔作為輸入&#xff0c;并直接返回相似度得分&#xff0c;而不是嵌入。該得分表示輸入查詢和文檔之間的相關性。 重排序器通常在…