• Linux文件编程(open read write close函数)



    前言

    本篇文章我们来讲解Linux中的文件编程,这篇文章会先介绍open read write函数。

    一、open函数

    open 函数是一个在 POSIX 标准中定义的函数,用于打开文件或者创建新文件。它是文件操作中很常用的一个函数,主要用于在程序中访问文件系统。

    下面是 open 函数的原型:

    #include 
    
    int open(const char *pathname, int flags, mode_t mode);
    
    • 1
    • 2
    • 3

    参数说明:

    pathname:要打开或创建的文件路径名。

    flags:文件打开的标志,用来指定打开方式和操作权限。

    mode:新创建文件的权限(仅在创建新文件时有效)。

    open 函数返回一个非负整数,称为文件描述符,它是用于标识打开文件的唯一值。如果函数执行失败,则返回 -1,表示出错。

    下面是一些常用的 flags 参数的取值:

    O_RDONLY:只读方式打开文件。
    O_WRONLY:只写方式打开文件。
    O_RDWR:读写方式打开文件。
    O_CREAT:如果文件不存在,则创建文件。
    O_APPEND:追加方式打开文件,写入内容会追加到文件末尾。
    O_TRUNC:如果文件存在,将其内容截断为0,即清空文件。

    下面是一些常用的 mode 参数的取值:

    S_IRUSR:用户具有读权限。
    S_IWUSR:用户具有写权限。
    S_IXUSR:用户具有执行权限。
    S_IRGRP:用户组具有读权限。
    S_IWGRP:用户组具有写权限。
    S_IXGRP:用户组具有执行权限。
    S_IROTH:其他用户具有读权限。
    S_IWOTH:其他用户具有写权限。
    S_IXOTH:其他用户具有执行权限。

    当前目录下不存在1.txt文件,我们使用open函数来创建并打开一个1.txt文件:
    在这里插入图片描述

    示例代码:

    #include 
    #include 
    #include 
    #include 
    
    int main(void)
    {
        int fd = 0;
    
        fd = open("1.txt", O_RDWR | O_CREAT);
    
        if(fd == -1)
        {
            printf("open 1.txt is err\n");
            return -1;
        }
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果:
    在这里插入图片描述
    在这里我们可以看到整个文件是红色的,因为我们在创建时没有给任何权限,那么这里我们在创建文件时给这个文件一些权限:

    #include 
    #include 
    #include 
    #include 
    
    int main(void)
    {
        int fd = 0;
    
        fd = open("1.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
    
        if(fd == -1)
        {
            printf("open 1.txt is err\n");
            return -1;
        }
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    二、read函数

    read 函数是一个系统调用,用于从已打开文件的文件描述符中读取数据。它的原型如下:

    #include 
    
    ssize_t read(int fd, void *buffer, size_t count);
    
    • 1
    • 2
    • 3

    参数解释:

    fd 是文件描述符,指定要读取数据的文件或设备。

    buffer 是一个指针,指向用于存储读取数据的缓冲区。

    count 是要读取的字节数,指定要从文件中读取的数据量。

    read 函数从文件描述符指定的文件位置开始读取数据,并将其存储到提供的缓冲区中。它返回实际读取的字节数。如果 read 函数返回0,表示已到达文件末尾。如果返回负值,表示读取出错,具体的错误码会存储在全局变量 errno 中供用户程序查询。

    使用 read 函数时,需要注意以下几点:

    1.在调用 read 之前,应确保文件已经被成功打开并获得有效的文件描述符。

    2.缓冲区的大小应足够大,以容纳要读取的数据。

    3.返回的字节数可能小于请求的字节数 count,特别是在读取非阻塞文件描述符时,这是正常的情况。

    4.多次调用 read 函数可以连续读取更多的数据,直到返回值为0,表示已读取完文件。

    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(void)
    {
        int fd = 0;
        char buf[1024];
        int len = 0;
    
        fd = open("1.txt", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); //打开文件,如果不存在则创建文件为可读可写
    
        if(fd == -1)
        {
            printf("open 1.txt is err\n");
            return -1;
        }
    
        len = read(fd, buf, 1024);
    
        if(len != -1)
        {
            printf("read buf : %s len : %d\n", buf, len);
        }
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    先在vi编辑器中修改文件中的内容:
    在这里插入图片描述
    运行结果:
    在这里插入图片描述

    三、write函数

    write 函数是一个系统调用,用于将数据写入已打开文件的文件描述符中。它的原型如下:

    #include 
    
    ssize_t write(int fd, const void *buffer, size_t count);
    
    • 1
    • 2
    • 3

    参数解释:

    fd 是文件描述符,指定要写入数据的文件或设备。
    buffer 是一个指针,指向包含要写入的数据的缓冲区。
    count 是要写入的字节数,指定要写入的数据量。
    write 函数将 count 字节的数据从 buffer 中写入到文件描述符指定的文件中。它返回实际写入的字节数。如果返回负值,表示写入出错,具体的错误码会存储在全局变量 errno 中供用户程序查询。

    使用 write 函数时,需要注意以下几点:

    1.在调用 write 之前,应确保文件已经被成功打开并获得有效的文件描述符。

    2.缓冲区中至少包含 count 字节的数据。

    3.返回的字节数可能小于请求的字节数 count,特别是在写入非阻塞文件描述符时,这是正常的情况。

    4.可以多次调用 write 函数来连续写入更多的数据。

    示例代码:

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(void)
    {
        int fd = 0;
        char buf[1024];
        int len = 0;
    
        fd = open("1.txt", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); //打开文件,如果不存在则创建文件为可读可写,并且将文件内容全部清除
    
        if(fd == -1)
        {
            printf("open 1.txt is err\n");
            return -1;
        }
    
        len = write(fd, "Hello", 6);
        if(len == -1)
        {
            printf("write err\n");
        }
    
        lseek(fd, 0, SEEK_SET);
    
        len = read(fd, buf, 1024);
    
        if(len != -1)
        {
            printf("read buf : %s len : %d\n", buf, len);
        }
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    运行结果:
    在这里插入图片描述

    四、open read write函数本质

    当调用 open、read、write 等文件相关的函数时,通常会触发系统调用(syscall),进入操作系统内核执行相应的操作。系统调用是用户程序与操作系统之间的接口,允许用户程序请求操作系统提供的服务和资源。

    在执行系统调用时,用户程序通过特殊的指令(例如 x86 架构上的 int 0x80 或 syscall 指令)将控制权转移到操作系统内核。操作系统根据系统调用号识别用户请求的具体服务,并执行相应的操作。

    系统调用的执行通常会引起特权转换(从用户模式切换到内核模式),因为内核需要访问受保护的资源和执行特权指令。在这个过程中,会触发一个异常(如 ARM 架构中的 SVC 异常),将控制权转移到内核中的异常处理程序。

    异常处理程序在内核中执行所需的操作,例如打开文件、读写文件等。一旦操作完成,控制权将返回到用户程序,继续执行后续的指令。

    因此,当调用 open、read、write 等文件相关函数时,通常会触发 SVC 异常,并进入内核执行相应的文件操作。

    五、close函数

    close 函数用于关闭打开的文件描述符。在使用完文件后,应该调用 close 函数来释放系统资源并确保数据的完整性。

    函数原型如下:

    #include 
    
    int close(int fd);
    
    • 1
    • 2
    • 3

    其中,fd 是需要关闭的文件描述符。如果关闭成功,返回值为0;如果发生错误,返回值为-1。

    close 函数的主要作用如下:

    1.释放文件描述符:调用 close 函数会释放文件描述符,并使其可供其他程序使用。这是一种良好的资源管理实践,避免文件描述符的浪费。

    2.刷新缓冲区:在关闭文件之前,close 函数会自动刷新文件的缓冲区,确保所有的数据都被写入到磁盘中。这样可以避免数据的丢失或不一致。

    3.断开与文件的连接:通过关闭文件描述符,close 函数会断开程序与文件之间的连接,不再对文件进行读写操作。这是确保文件的安全性以及其他进程能够访问文件的重要步骤。

    总结

    本篇文章就讲解到这里,下篇文章继续讲解Linux文件编程。

  • 相关阅读:
    【冒泡排序】
    ubuntu 22.04配置静态ip
    Amazon EC2 Serial Console 现已在其他亚马逊云科技区域推出
    (附源码)ssm捐赠救助系统 毕业设计 060945
    基于SSM的外卖点餐系统设计与实现
    牛客[NOIP2016]蚯蚓
    CCF推荐国际会议接收率(持续更新)
    【从零开始学习 SystemVerilog】11.1、SystemVerilog 断言—— Assertions Introduction(断言概述)
    SparkStreaming 案例实操 完整使用 (第十七章)
    爬虫之xpath
  • 原文地址:https://blog.csdn.net/m0_49476241/article/details/131889241