天天看點

linux 系統調用 read,write和lseek 使用

read系統調用

  • 頭檔案 ​

    ​#include <unistd.h>​

  • 函數使用 ​

    ​ssize_t read(int fd, void *buf, size_t count)​

    ​​ read 函數會從檔案描述符​

    ​fd​

    ​中讀取指定的​

    ​count​

    ​長度的内容,并且将讀到的結果放入到buf緩沖區中
  • 傳回值

    ​​

    ​count​

    ​​ 讀取成功,則會傳回讀到的位元組數

    ​​

    ​小于count​

    ​​ 表示同樣讀取成功,隻是​

    ​fd​

    ​​從current offset中并未讀到count的位元組數

    ​​

    ​0​

    ​​ 表示讀到了檔案的末尾

    ​​

    ​-1​

    ​​ 表示讀取失敗,可能​

    ​fd​

    ​已經關閉,可能讀到了一個管道,或者read被核心信号中斷

注意:

read操作會從目前檔案的檔案偏移處進行讀取,同時 檔案偏移會随着讀到的長度進行移動。如果目前檔案的偏移位址是在上一個檔案的結束,那就無法讀到​​

​fd​

​​中的内容。是以這裡如果想要讀取檔案中的内容,在使用​

​read​

​​系統調用之前需要重新設定偏移位址​

​lseek​

其他較長的描述可以參考​

​man 2 read​

write系統調用

  • 頭檔案 ​

    ​#include <unistd.h>​

  • 函數使用 ​

    ​ssize_t write(int fd, const void *buf, size_t count)​

    ​​ write函數會向檔案描述符​

    ​fd​

    ​中寫入​

    ​count​

    ​ bytes的内容,内容的來源是​

    ​buf​

  • 傳回值

    ​​

    ​count​

    ​​ 寫入的資料大小 bytes

    ​​

    ​0​

    ​​ 沒有寫入任何東西

    ​​

    ​-1​

    ​ 表示寫入失敗

lseek系統調用

  • 頭檔案

    ​#include <unistd.h>​

    ​​

    ​#include <sys/types.h>​

  • 函數使用 ​

    ​off_t lseek(int fd, off_t offset, int whence)​

    ​ lseek函數會将檔案描述符​

    ​fd​

    ​所代表的目前檔案偏移位址移動指定的偏移量​

    ​offset​

    ​,移動方式是通過​

    ​whence​

    ​ 其中​

    ​whence​

    ​有如下幾種:

    a. ​

    ​SEEK_SET​

    ​ 如果offset為0,則讀寫位置移動到開頭。如果不為0,則讀寫位置在目前位置基礎上向前移動​

    ​offset​

    ​個位元組

    b. ​

    ​SEEK_CUR​

    ​将讀寫位置移動到目前位置後再增加offset個位元組

    c. ​

    ​SEEK_END​

    ​ 将讀寫位置移動到檔案結尾後再增加offset個位元組
  • 傳回值

    ​offset​

    ​ 成功則傳回該值。該offset并非參數傳入的​

    ​offset​

    ​,而是移動偏移量之後 目前偏移量相對于檔案開頭的偏移量值

    ​-1​

    ​ 移動偏移量失敗

代碼案例

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>

int main()
{
        int fd;
        char buf[100];
        memset(buf,0,sizeof(buf));
        fd = open("write.test",O_RDWR|O_APPEND); //追加可 讀寫方式打開了一個檔案
        size_t x = write(fd,"my name is hello \n",20);  //寫入20個字元串
        printf("you have writed %d words to the buffer and off is %d\n",x,fd);
        //close(fd); //此時close,則後續的lseek都傳回 -1
        
        //如果此時不進行lseek,則後續read讀出的buf是空的。lseek此時使用`SEEK_SET`的`whence`,即跳到檔案開頭進行偏移
        off_t k = lseek(fd,10,SEEK_SET); 
        printf("The file offset is %d\n",k);
        
        size_t t = read(fd,buf,20);
        printf("you have read %d words and %s content\n",t,buf);
        
        close(fd);
        return 0;
}      
[root@localhost ~]# ./a.out 
you have writed 20 words to the buffer and off is 3
The file offset is 10 //向前移動10個字元,最後讀出的内容是 “hello \n”
you have read 10 words and  hello 
 content
[root@localhost ~]# cat write.test 
my name is hello      

繼續閱讀