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

简介: Linux文件编程(open read write close函数)

前言

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

一、open函数

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

下面是 open 函数的原型:

#include <fcntl.h>
int open(const char *pathname, int flags, mode_t mode);

参数说明:

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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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;
}

运行结果:

在这里我们可以看到整个文件是红色的,因为我们在创建时没有给任何权限,那么这里我们在创建文件时给这个文件一些权限:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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;
}

二、read函数

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

#include <unistd.h>
ssize_t read(int fd, void *buffer, size_t count);

参数解释:

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

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

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

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

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

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

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

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

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

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
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;
}

先在vi编辑器中修改文件中的内容:

运行结果:

三、write函数

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

#include <unistd.h>
ssize_t write(int fd, const void *buffer, size_t count);

参数解释:

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

buffer 是一个指针,指向包含要写入的数据的缓冲区。

count 是要写入的字节数,指定要写入的数据量。

write 函数将 count 字节的数据从 buffer 中写入到文件描述符指定的文件中。它返回实际写入的字节数。如果返回负值,表示写入出错,具体的错误码会存储在全局变量 errno 中供用户程序查询。

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

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

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

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

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

示例代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
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;
}

运行结果:

四、open read write函数本质

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

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

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

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

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

五、close函数

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

函数原型如下:

#include <unistd.h>
int close(int fd);

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

close 函数的主要作用如下:

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

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

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

总结

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


目录
打赏
0
0
0
0
14
分享
相关文章
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
75 34
|
1月前
|
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
48 17
|
1月前
|
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
59 26
Linux shell编程学习笔记30:打造彩色的选项菜单
Linux shell编程学习笔记30:打造彩色的选项菜单
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
135 13
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
Linux shell编程学习笔记82:w命令——一览无余
Linux shell编程学习笔记82:w命令——一览无余
python执行linux系统命令的几种方法(python3经典编程案例)
文章介绍了多种使用Python执行Linux系统命令的方法,包括使用os模块的不同函数以及subprocess模块来调用shell命令并处理其输出。
204 0
Linux VFS中write系统调用实现原理【转】
转自:http://blog.chinaunix.net/uid-28362602-id-3425881.html 目录 用户空间的write函数在内核里面的服务例程为sys_write Vfs_write函数实现原理   WORD里面的目录复制过来似乎不能直接用。
901 0
|
1月前
|
Linux系统之whereis命令的基本使用
Linux系统之whereis命令的基本使用
74 24
Linux系统之whereis命令的基本使用
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等