6. 文件IO

文件IO: Linux内核提供的文件操作接口。属于系统调用。

学习接口:

  1. 打开文件 : open()

  2. 读文件、写文件 : read() 、write()

  3. 关闭文件 : close()

函数接口:

  • 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_CREAT  :创建
    O_TRUNC : 清空
    O_APPEND : 追加
    "r"    O_RDONLY
    "r+"   O_RDWR
    "w"    O_WRONLY | O_TRUNC | O_CREAT, 0664
    "w+"   O_RDWR | O_TRUNC | O_CREAT,0664
    "a"    O_WRONLY | O_CREAT | O_APPEND, 0664
    "a+"   O_RDWR | O_CREAT | O_APPEND, 0664
    mode:用户自己、同组用户、其他用户对该文件的读写执行权限
         (mode & ~umask)
         普通文件:0664
         权限给满:0777
                 rwxrwxr-x
返回值:
    成功:文件描述符
    失败:-1

文件描述符:

当打开一个文件时,系统会为已打开的文件分配一个文件描述符用来标记该文件。

文件描述符:小的,非负的整形数据

操作系统默认可分配出的文件描述符:0-1023: 总共1024个

文件描述符的分配原则:最小未被使用

系统默认已打开的文件:

标准IO: 文件IO

FILE * int

stdin 0(STDIN_FILENO)

stdout 1(STDOUT_FILENO)

stderr 2 (STDERR_FILENO)

  • close

 #include <unistd.h>
​
int close(int fd);
功能:关闭文件
参数:
    fd:文件描述符
返回值:
    成功:0
    失败:-1
    
注意:
    只打开文件,使用完不关闭文件会造成文件描述符泄露。

  • write

 ssize_t write(int fd, const void *buf, size_t count);
功能:向文件中写入数据
参数:
    fd :要写入的文件描述符
    buf:要写入的数据首地址
    count:希望写入的字节数
返回值:
    成功:实际写入的字节数
    失败:-1
  • read

ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读取数据
参数:
    fd:要读的文件的文件描述符
    buf:存储读取数据的空间首地址
    count:希望读到的字节数
返回值:
    成功:返回实际读到的字节数
    失败:-1
    到达文件文件末尾:0

文件拷贝:

int file_copy(const char *srcfile, const char *dstfile)
{
    int fdsrc = open(srcfile, O_RDONLY);
    int fddst = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);
    if (-1 == fdsrc || -1 == fddst)
    {
        printf("open error\n");
        return -1;
    }
    char buff[1024] = {0};
    ssize_t size = 0;
    while ((size = read(fdsrc, buff, sizeof(buff))) > 0)
    {
        write(fddst, buff, size);
    }
​
    close(fdsrc);
    close(fddst);
​
    return 0;
​
}
​

文件定位函数:

lseek()

off_t lseek(int fd, off_t offset, int whence);
功能:重新定位文件的读写位置
参数:
    fd:文件描述符
    offset:偏移量
    whence:要偏移的起始位置
        SEEK_SET :从文件开头偏移
        SEEK_CUR: 从当前读写位置偏移
        SEEK_END :从文件末尾偏移
返回值:
    成功:返回当前读写位置到文件开头的偏移量
    失败:-1

7 .文件IO和标准IO的区别

标准IO文件IO
操作对象:FILE *(文件流指针)操作对象:fd (文件描述符)
标准C库函数,可移植性强Linux系统调用,可移植性弱
有缓冲区,减少用户层和内核层反复切换,提高效率无缓冲区,实时性好
主要用在对普通文件操作普通文件、硬件设备类相关的文件

缓冲区:

  • 行缓冲

    默认大小1024字节(1K),主要使用在人机交互终端上。

    刷新条件:

    • 遇到'\n'刷新

    • 程序结束刷新

    • 使用fflush()强制刷新

    • 缓冲区满时自动刷新

  • 全缓冲

    默认大小4096字节(4K),文件交互

    刷新条件:

    • 程序结束刷新

    • 文件关闭自动刷新

    • 全缓冲区满时自动刷新

    • 使用fflush()强制刷新

  • 无缓冲

    0k, ,出错信息输出,标准出错设备

    stderr

8.目录IO

  1. 打开目录文件:opendir()

  2. 读目录文件 :readdir()

  3. 关闭目录文件 : closedir()

  • opendir

DIR *opendir(const char *name);
功能:打开目录文件并获得目录流指针
参数:
    name:目录名
返回值:
    成功:目录流指针
    失败:NULL

closedir

 int closedir(DIR *dirp);
功能:关闭目录文件
参数:
    dirp:目录流指针
返回值:
    成功: 0
    失败:-1

readdir

struct dirent *readdir(DIR *dirp);
功能:从目录流中读取数据
参数:
    dirp:目录流指针
返回值:
    成功:struct dirent 指针,代表读到的文件信息
    失败:NULL
    文件末尾:NULL
    
  struct dirent {
               ino_t          d_ino;       /* Inode number */
               off_t          d_off;       /* Not an offset; see below */
               unsigned short d_reclen;    /* Length of this record */
               unsigned char  d_type;      /* Type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* Null-terminated filename */
           };
​

命令:

mkdir:创建文件夹

touch:创建普通文件

open();

fopen();

mkdir();

int mkdir(const char *pathname, mode_t mode);
功能:创建一个目录文件(文件夹)
参数:
    pathname:目录名称
    mode:目录文件的操作权限
返回值:
    成功:0
    失败:-1

目录遍历:

int main(void)
{
    DIR *pdir = opendir("/dev");
    if (NULL == pdir)
    {
        printf("opendir error\n");
        return -1;
    }
    
    while (1)
    {
        struct dirent *pinfo = readdir(pdir);
        if (NULL == pinfo)
        {
            break;
        }
        if ('.' == pinfo->d_name[0])
        {
            continue;
        }
        printf(" %s : %ld\n", pinfo->d_name, pinfo->d_ino);
    }
​
    closedir(pdir);
    return 0;
}

9. 其他

int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
功能:将格式化后的字符串写入到stream文件流代表的文件中。
int dprintf(int fd, const char *format, ...);
功能:将格式化后的字符串写入到fd所代表的文件中。
*int sprintf(char *str, const char *format, ...);
功能:将格式化后的字符串写入到字符型数组中
     字符串的拼接,格式化
     可以将整形数据、浮点型数据等转换成字符串
char *strtok(char *str, const char *delim);
功能:字符串截取函数
参数:
    str:要截取的原始字符串
    delim:要截断的分隔符
返回值:
    成功:截取到的子字符串的首地址
    失败:NULL(已经到字符串末尾)

errno is set;

出错处理函数:

strerror:

char *strerror(int errnum);
功能:将错误码转换成对应的错误信息字符串
参数:
    errnum:错误码:errno
返回值:
    成功:返回错误码对应的字符串首地址
    失败:NULL

perror

void perror(const char *s);
功能:打印自己的出错处理信息和系统系统给出的出错原因。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐