zoukankan      html  css  js  c++  java
  • 文件I/O相关函数

    open()和openat()函数:

    #include <fcntl.h>
    
    // 成功返回文件描述符,出错返回-1
    int open(const char *path, int oflag, ... /* mode_t mode */);
    int openat(int fd, const char *path, int oflag, ... /* mode_t mode */);
    int creat(const char *path, mode_t mode);
    // creat()因为历史原因,作为弥补open()不能打开一个尚未存在的文件的这个缺憾而存在
    // 而随着opne()提供了O_CREAT和O_TRUNC之后就不需要creat()函数了
    // mode参数在打开一个不存在的文件时(创建新文件)需要指定
    // path参数为绝对路径: fd参数被忽略,open()与openat()效果相同
    // path参数为相对路径: fd为该相对路径的起始地址
    // openat()函数实际上就是为了可以使用相对路径打开目录中的文件和避免TOCTTOU错误产生的

    mode参数的值有点类似与创建IPC对象所用的mode常值,但有点区别,以下时open()使用的mode值:
    S_IRUSR 用户读
    S_IWUSR 用户写
    S_IXUSR 用户执行
    S_IRGRP 组读
    S_IWGRP 组写
    S_IXGRP 组执行
    S_IROTH 其他用户读
    S_IWOTH 其他用户写
    S_IXOTH 其他用户执行

    oflag参数取值:
    O_RDONLY, O_WRONLY, or O_RDWR
    可选值
    O_APPEND, O_CLOEXEC, O_CREAT, O_DIRECTORY, O_EXCL, O_NOCTTY, O_NOFOLLOW, O_NONBLOCK,
    O_SYNC, O_TRUNC, O_TTYINIT
    同样的函数,在Linux上的实现及相关实现http://man7.org/linux/man-pages/man2/open.2.html

    #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);
    
    int creat(const char *pathname, mode_t mode);
    
    int openat(int dirfd, const char *pathname, int flags);
    int openat(int dirfd, const char *pathname, int flags, mode_t mode);

    close()函数:

    #include <unistd.h>
    
    // 关闭一个打开着的文件,成功返回0,出错返回-1
    int close(int fd);

    lseek()函数:

    #include <unistd.h>
    
    // 设置文件偏移量,成功返回新的文件偏移量,出错返回-1
    off_t lseek(int fd, off_t offset, int whence);
    // fd为被设置的文件的描述符,offset为偏移量(offset可正可负),whence决定从文件哪个位置怎么偏移

    whence参数取值:
    SEEK_SET: 将文件偏移量设置为距文件开始处offset个字节
    SEEK_CUR: 将文件偏移量设置为当前偏移量加上offset
    SEEK_END: 将文件偏移量设置为文件长度加上offset

    注意:有的文件允许当前偏移量为负值,因此在检查lseek()执行是否成功时,应该检查返回值
    是否为-1,而不能检查其是否小于零

    read()、write()、pread()、pwrite()函数:

    #include <unistd.h>
    
    // 从文件读取数据和向文件写数据
    // 成功则返回读或写的字节数,出错返回-1
    ssize_t read(int fd, void *buf, size_t nbytes);
    ssize_t write(int fd, const void *buf, size_t nbytes);
    
    // 相当于先调用lseek()后再调用read()或write(),但相对于分开二个函数,此处函数操作是原子的
    ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);
    ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);

    dup()和dup2()函数:

    #include <unistd.h>
    
    // 复制一个现有的文件描述符,若成功返回新的文件描述符,出错返回-1
    int dup(int fd);
    int dup2(int fd, int fd2);

    相对于dup(),dup2()可以用fd2指定新的文件描述符值
    若果fd2已经打开,则dup2()先将其关闭,当fd2等于fd,则返回fd2,而不关闭它
    注意:不要把文件描述符当做int,认为可以通过赋值语句赋值一个文件描述符

    文件同步相关函数:

    #include <unistd.h>
    
    void sync(void);
    // 成功返回0,出错返回-1
    int fsync(int fd);
    int fdatasync(int fd);

    在向文件中写入数据时,内核会先将数据复制到缓冲区,然后排入队列,晚些时候在写入磁盘(延迟写)
    在为了保证实际文件系统与缓冲区中内容一致性时,我们使用上述的三个函数
    sync()将所有修改过的块缓冲区排入写队列,然后返回,并不等待实际的写磁盘操作是否完成
    fsync()同步时,只对fd指定的文件有用,且等待实际写磁盘操作结束才返回
    fdatasync()与fsync()类似,但只更新文件数据,而fsync()出数据外还更新文件属性

    fcntl()函数:

    #include <fcntl.h>
    
    // 若成功,返回值由cmd参数决定,出错返回-1
    int fcntl(int fd, int cmd, ... /* arg */);


    关于fcntl()函数的man文档中的描述:https://linux.die.net/man/2/fcntl
    具体解释(中文):https://www.cnblogs.com/xuyh/p/3273082.html

    ioctl()函数:

    #include <unistd.h>
    
    int ioctl(int fd, int request, ... );
  • 相关阅读:
    C计算double能精确到多少位
    C计算int最大值、最小值
    AndroidStudio右键new无activity
    java替换特殊字符串 $
    lamda表达式排序
    docker toolbox 设置镜像加速
    tomcat优化
    nginx配置相关
    SQL 优化
    elasticsearch 概念初识
  • 原文地址:https://www.cnblogs.com/lnlin/p/9940140.html
Copyright © 2011-2022 走看看