linux open write lseek的API和应用

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
    • 成功返回实际读到的字节数
    • 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的文件

#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);
  
}

猜你喜欢

转载自www.cnblogs.com/xiaoshiwang/p/10758224.html