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文件编程。


相关文章
|
安全 算法 Ubuntu
Linux(openssl)环境:编程控制让证书自签的技巧。
总结:在Linux环境中,OpenSSL是一个非常实用的工具,可以帮助我们轻松地生成自签名证书。通过上述三个简单步骤,即可为内部网络、测试环境或开发环境创建自签名证书。但在公共访问场景下,建议购买经过权威认证机构签发的证书,以避免安全警告。
746 13
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
777 34
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
338 26
|
JavaScript Ubuntu Linux
如何在阿里云的linux上搭建Node.js编程环境?
本指南介绍如何在阿里云Linux服务器(Ubuntu/CentOS)上搭建Node.js环境,包含两种安装方式:包管理器快速安装和NVM多版本管理。同时覆盖全局npm工具配置、应用部署示例(如Express服务)、PM2持久化运行、阿里云安全组设置及外部访问验证等步骤,助你完成开发与生产环境的搭建。
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
358 17
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
834 13
|
11月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
1047 1
二、Linux文本处理与文件操作核心命令
|
11月前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
718 137
|
11月前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1652 58
|
10月前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
1557 2