linux 讀寫文件 open write lseek的API和應用

linux下的文件讀寫

1, open

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
  • pathname:文件路徑和名
  • flags
    • 必選項
      • O_RDONLY:只讀
      • O_WRONLY:只寫
      • O_RDWR:讀寫
    • 可選項
      • O_APPEND
      • O_CREAT
        • O_EXCL
        • mode:若是是建立文件,則必須指定文件的權限,最好算出來的權限:mode & ~umask
  • 返回值:返回最小的可用文件描述符,失敗返回-1,並設置errno

例子:模擬touch命令linux

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char* argv[]){
  int fd = open(argv[1], O_RDONLY|O_CREAT|O_EXCL, 0666);
  close(fd);
  return 0;
}

0666 & ~0002 = 0664,因此建立出來的文件的權限是:-rw-rw-r--c++

2,read

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
  • fd:文件描述符
  • buf:讀到哪裏
  • conut:讀多少個字節
  • 返回值
    • 失敗返回-1,並設置errno
    • 若是文件描述符是非阻塞的時候,read不到的時候,返回值也是-1,這個-1不表明read失敗,因此要判斷errno的值,這時errno的值爲【11】,用perror打印出的錯誤信息是【Resource temporarily unavailable】
    • 成功返回實際讀到的字節數
    • 0表明讀到文件的末尾了

3,write

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
  • fd:文件描述符
  • buf:從哪裏寫
  • conut:寫多少個字節
  • 返回值
    • 失敗返回-1,並設置errno
    • 成功返回實際寫出去的字節數
    • 0表明什麼也沒寫進去

例子:模擬cat命令微信

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char* argv[]){
  int fd = open(argv[1], O_RDONLY);
  char buf[64] = {0};
  int ret = 0;
  
  while((ret = read(fd, buf, sizeof buf)) > 0){
    write(STDOUT_FILENO, buf, ret);
  }
  close(fd);
  return 0;
}

4,lseek

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);
  • fd:文件描述符
  • offset:偏移的數量
  • whence:從哪裏開始偏移
    • SEEK_SET:文件描述符的開始位置
    • SEEK_CUR:文件描述符的當前位置
    • SEEK_END:文件描述符的末尾位置
  • 返回值
    • 成功:返回當前位置到開始位置的長度
    • 失敗:返回-1,並設置errno

例子1:把字符串「helloworld」寫入一個文件,而後讀取這個文件,把「helloworld」從文件中讀取出來,並打印到終端。學習

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char* argv[]){
  int fd = open(argv[1], O_RDWR|O_CREAT, 0666);
  write(fd, "helloworld\n", 11);

  //這裏必須使用lseek,來調整文件指針的位置,設置文件指針設置到文件的開始位置。
  lseek(fd, 0, SEEK_SET);
  char buf[20] = {0};
  int ret = read(fd, buf, sizeof buf);
  write(STDOUT_FILENO, buf, ret);
  
  close(fd);
  return 0;
}

read和write的內幕:雖然read和write的參數裏沒有,文件指針所在位置的參數,可是,執行read或者write後,文件指針所在位置會被自動調整到:【當前位置+讀入或者寫入的字節數】的位置。

例子2:計算文件的大小指針

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]){
  int fd = open(argv[1], O_RDWR);
    
  //open後,文件指針的位置在文件開頭
  //由於:lseek返回當前位置到開始位置的長度
  //因此用lseek移動到了文件末尾,這時lseek的返回值就是文件的大小
  int ret = lseek(fd, 0, SEEK_END);
  printf("file size:%d\n", ret);
  close(fd);
}

例子3:建立文件大小爲1024的文件code

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]){

  int fd = open(argv[1], O_WRONLY|O_CREAT, 0666);
  //打開後文件指針在文件的開始位置,而後從開始位置移動1023個字節,而後再調用write,
  //注意不調用後面的write的話,建立的文件的大小是爲0的。
  lseek(fd, 1023, SEEK_SET);
  write(fd, "a", 1);
  close(fd);
  
}

c/c++ 學習互助QQ羣:877684253

本人微信:xiaoshitou5854

相關文章
相關標籤/搜索