• 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命令

    #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--

    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
    ", 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
    ", ret);
      close(fd);
    }
    
    

    例子3:创建文件大小为1024的文件

    #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

  • 相关阅读:
    【转】Shell编程基础篇-上
    【转】inotify+rsync实现实时同步
    Spring
    jdk,jre,tommcat配置问题
    Java前后台开发
    前端组件学习(一)
    报表工具进阶(二)
    查询时异步刷新问题--用到了ajax
    学习jaspersoft/JasperReport
    利用SQLYog操作数据库mysql
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/10758224.html
Copyright © 2020-2023  润新知