当前位置: 首页 > news >正文

【Linux操作系统】举例解释Linux系统编程中文件io常用的函数

在Linux系统编程中,文件IO操作是非常常见和重要的操作之一。通过文件IO操作,我们可以打开、读取、写入和关闭文件,对文件进行定位、复制、删除和重命名等操作。本篇博客将介绍一些常用的文件IO操作函数。
在这里插入图片描述

文章目录

    • 1. open()
      • 1.1 原型、参数及返回值说明
        • 1.1.1 原型:
        • 1.1.2 参数说明:
        • 1.1.3 返回值:
      • 1.2 函数示例
      • 1.3 代码解释
    • 2. close()
      • 2.1 原型、参数及返回值说明
        • 2.1.1 原型:
        • 2.1.2 参数:
        • 2.1.3 返回值:
      • 2.2 函数示例
      • 2.3 代码解释
    • 3. read()
      • 3.1 原型、参数及返回值说明
        • 3.1.1 原型:
        • 3.1.2 参数:
        • 3.1.3 返回值:
      • 3.2 函数示例
      • 3.3 代码解释
    • 4. write()
      • 4.1 原型、参数及返回值说明
        • 4.1.1 原型:
        • 4.1.2 参数:
        • 4.1.3 返回值:
      • 4.2 函数示例
      • 4.3 代码解释
    • 5. lseek()
      • 5.1 原型、参数及返回值说明
        • 5.1.1 原型:
        • 5.1.2 参数:
        • 5.1.3 返回值:
      • 5.2 函数示例
      • 5.3 代码解释
    • 6. stat()
      • 6.1 原型、参数及返回值说明
        • 6.1.1 原型:
        • 6.1.2 参数:
        • 6.1.3 返回值:
      • 6.2 函数示例
      • 6.3 代码解释
    • 7. fcntl()
      • 7.1 原型、参数及返回值说明
        • 7.1.1 原型:
        • 7.1.2 参数:
        • 7.1.3 返回值:
      • 7.2 函数示例
      • 7.3 代码解释
    • 总结

1. open()

1.1 原型、参数及返回值说明

1.1.1 原型:

open()函数是Linux系统编程中常用的文件IO操作函数之一。它用于打开文件并返回一个文件描述符,以便后续的文件读写操作。
open()函数的原型如下:

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

1.1.2 参数说明:

  1. pathname:要打开的文件路径名。
  2. flags:打开文件的模式标志,可以是以下几种模式的组合:
    • O_RDONLY:只读模式打开文件。
    • O_WRONLY:只写模式打开文件。
    • O_RDWR:读写模式打开文件。
    • O_CREAT:如果文件不存在,则创建文件。
    • O_EXCL:与O_CREAT一同使用,如果文件已存在,则返回错误。
    • O_TRUNC:如果文件存在且以可写模式打开,则将文件截断为0。
    • O_APPEND:在文件末尾追加数据。
  3. mode 创建文件时的访问权限,只有在使用O_CREAT时才有效。
    可以使用如下几个宏来设置权限:
    • S_IRUSR:用户读权限。
    • S_IWUSR:用户写权限。
    • S_IXUSR:用户执行权限。
    • S_IRGRP:组读权限。
    • S_IWGRP:组写权限。
    • S_IXGRP:组执行权限。
    • S_IROTH:其他用户读权限。
    • S_IWOTH:其他用户写权限。
    • S_IXOTH:其他用户执行权限。

1.1.3 返回值:

  • 成功:返回一个非负整数的文件描述符,用于后续的文件IO操作。
  • 失败:返回-1,并设置errno变量来指示错误类型。

1.2 函数示例

下面是一个使用open()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>int main() {int fd;// 打开文件fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);if (fd == -1) {perror("open");return errno;}// 写入数据char buffer[] = "Hello, world!";ssize_t ret = write(fd, buffer, sizeof(buffer) - 1);if (ret == -1) {perror("write");close(fd);return errno;}// 关闭文件close(fd);return 0;
}

1.3 代码解释

在上述示例中,我们首先使用open()函数以只写模式打开一个文件example.txt。如果文件不存在,则创建该文件,并设置访问权限为用户可读可写。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

接下来,我们使用write()函数向文件中写入数据。在本例中,我们写入了字符串"Hello, world!"。如果写入数据失败,我们同样使用perror()函数打印错误信息,并在关闭文件前返回errno变量。

最后,我们使用close()函数关闭文件。

2. close()

2.1 原型、参数及返回值说明

2.1.1 原型:

close()函数是Linux系统编程中用于关闭文件的函数。它接受一个文件描述符作为参数,并返回一个整数值来指示操作是否成功。

close()函数的原型如下:

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

2.1.2 参数:

  • fd:要关闭的文件描述符。

2.1.3 返回值:

  • 成功:返回0。
  • 失败:返回-1,并设置errno变量来指示错误类型。

2.2 函数示例

下面是一个使用close()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>int main() {int fd;// 打开文件fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open");return errno;}// 关闭文件int ret = close(fd);if (ret == -1) {perror("close");return errno;}return 0;
}

2.3 代码解释

在上述示例中,我们首先使用open()函数以只读模式打开一个文件example.txt,并将返回的文件描述符存储在变量fd中。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

接下来,我们使用close()函数关闭文件。如果关闭文件失败,我们同样使用perror()函数打印错误信息,并返回errno变量。

需要注意的是,关闭文件后,我们不应再对该文件描述符进行任何操作。

3. read()

3.1 原型、参数及返回值说明

3.1.1 原型:

read()函数是Linux系统编程中用于从文件中读取数据的函数。它接受一个文件描述符、一个缓冲区地址和一个读取的最大字节数作为参数,并返回实际读取的字节数。

read()函数的原型如下:

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

3.1.2 参数:

  • fd:要读取的文件的文件描述符。
  • buf:用于存储读取数据的缓冲区的地址。
  • count:要读取的最大字节数。

3.1.3 返回值:

  • 成功:返回实际读取的字节数。
  • 失败:返回-1,并设置errno变量来指示错误类型。

3.2 函数示例

下面是一个使用read()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>int main() {int fd;// 打开文件fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open");return errno;}// 读取数据char buffer[100];ssize_t ret = read(fd, buffer, sizeof(buffer));if (ret == -1) {perror("read");close(fd);return errno;}// 输出读取的数据printf("Read %ld bytes: %s\n", ret, buffer);// 关闭文件close(fd);return 0;
}

3.3 代码解释

在上述示例中,我们首先使用open()函数以只读模式打开一个文件example.txt,并将返回的文件描述符存储在变量fd中。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

接下来,我们使用read()函数从文件中读取数据。我们定义一个长度为100的缓冲区buffer,并将其作为参数传递给read()函数。read()函数将尽量读取count个字节的数据,并将其存储在缓冲区中。如果读取数据失败,我们同样使用perror()函数打印错误信息,并在关闭文件前返回errno变量。

最后,我们使用printf()函数输出读取的数据,并使用close()函数关闭文件。

需要注意的是,read()函数是一个阻塞函数,如果文件中没有足够的数据可读,它将一直等待直到有足够的数据可读或者发生错误。如果需要非阻塞地读取数据,可以使用fcntl()函数设置文件描述符为非阻塞模式。

4. write()

4.1 原型、参数及返回值说明

4.1.1 原型:

write()函数是Linux系统编程中用于向文件中写入数据的函数。它接受一个文件描述符、一个数据缓冲区地址和要写入的字节数作为参数,并返回实际写入的字节数。

write()函数的原型如下:

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

4.1.2 参数:

  • fd:要写入的文件的文件描述符。
  • buf:要写入的数据的缓冲区的地址。
  • count:要写入的字节数。

4.1.3 返回值:

  • 成功:返回实际写入的字节数。
  • 失败:返回-1,并设置errno变量来指示错误类型。

4.2 函数示例

下面是一个使用write()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>int main() {int fd;// 打开文件fd = open("example.txt", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);if (fd == -1) {perror("open");return errno;}// 写入数据char buffer[] = "Hello, World!";ssize_t ret = write(fd, buffer, sizeof(buffer) - 1);if (ret == -1) {perror("write");close(fd);return errno;}// 关闭文件close(fd);return 0;
}

4.3 代码解释

在上述示例中,我们首先使用open()函数以只写模式打开一个文件example.txt,并将返回的文件描述符存储在变量fd中。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

接下来,我们使用write()函数将数据写入文件中。我们定义一个字符串buffer,并将其作为参数传递给write()函数。write()函数将尽量写入count个字节的数据到文件中。如果写入数据失败,我们同样使用perror()函数打印错误信息,并在关闭文件前返回errno变量。

最后,我们使用close()函数关闭文件。

需要注意的是,write()函数是一个阻塞函数,如果文件无法立即接受写入的数据(例如,磁盘空间不足),它将一直等待直到可以写入数据或者发生错误。如果需要非阻塞地写入数据,可以使用fcntl()函数设置文件描述符为非阻塞模式。

5. lseek()

5.1 原型、参数及返回值说明

5.1.1 原型:

lseek()函数是Linux系统编程中用于在文件中定位读写位置的函数。它接受一个文件描述符、一个偏移量和一个起始位置作为参数,并返回新的读写位置。

lseek()函数的原型如下:

#include <unistd.h>off_t lseek(int fd, off_t offset, int whence);

5.1.2 参数:

  • fd:要定位的文件的文件描述符。
  • offset:偏移量,可以是正数、负数或零。
  • whence:起始位置,可以取以下三个值:
    • SEEK_SET:从文件开头开始计算偏移量。
    • SEEK_CUR:从当前读写位置开始计算偏移量。
    • SEEK_END:从文件末尾开始计算偏移量。

5.1.3 返回值:

  • 成功:返回新的读写位置。
  • 失败:返回-1,并设置errno变量来指示错误类型。

5.2 函数示例

下面是一个使用lseek()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>int main() {int fd;// 打开文件fd = open("example.txt", O_RDONLY);if (fd == -1) {perror("open");return errno;}// 定位读写位置off_t ret = lseek(fd, 5, SEEK_SET);if (ret == -1) {perror("lseek");close(fd);return errno;}// 读取数据char buffer[10];ssize_t n = read(fd, buffer, sizeof(buffer) - 1);if (n == -1) {perror("read");close(fd);return errno;}buffer[n] = '\0';printf("Data: %s\n", buffer);// 关闭文件close(fd);return 0;
}

5.3 代码解释

在上述示例中,我们首先使用open()函数以只读模式打开一个文件example.txt,并将返回的文件描述符存储在变量fd中。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

接下来,我们使用lseek()函数将读写位置定位到文件开头后的第5个字节。我们将文件描述符、偏移量和起始位置作为参数传递给lseek()函数。如果定位读写位置失败,我们同样使用perror()函数打印错误信息,并在关闭文件前返回errno变量。

然后,我们使用read()函数从文件中读取数据。我们定义一个缓冲区buffer,并将其作为参数传递给read()函数。read()函数将尽量读取count个字节的数据到缓冲区中。如果读取数据失败,我们同样使用perror()函数打印错误信息,并在关闭文件前返回errno变量。最后,我们在缓冲区末尾添加一个空字符,并使用printf()函数打印读取到的数据。

最后,我们使用close()函数关闭文件。

需要注意的是,lseek()函数可以用于定位读写位置,但并不会改变文件的大小。如果需要改变文件的大小,可以使用truncate()函数或ftruncate()函数。

6. stat()

6.1 原型、参数及返回值说明

6.1.1 原型:

stat()函数是Linux系统编程中用于获取文件信息的函数。它接受一个文件路径作为参数,并返回一个包含文件信息的结构体。

stat()函数的原型如下:

#include <sys/types.h>
#include <sys/stat.h>int stat(const char *pathname, struct stat *buf);

6.1.2 参数:

  • pathname:要获取信息的文件路径。
  • buf:用于存储文件信息的结构体指针。

6.1.3 返回值:

  • 成功:返回0。
  • 失败:返回-1,并设置errno变量来指示错误类型。

struct stat结构体包含了文件的各种信息,包括文件类型、权限、大小、创建时间、修改时间等

下面是struct stat结构体的定义:

struct stat {dev_t     st_dev;         // 文件所在设备的IDino_t     st_ino;         // 文件的inode号mode_t    st_mode;        // 文件的类型和权限nlink_t   st_nlink;       // 文件的硬链接数uid_t     st_uid;         // 文件的所有者IDgid_t     st_gid;         // 文件的所有者组IDdev_t     st_rdev;        // 如果文件是设备文件,则为设备的IDoff_t     st_size;        // 文件的大小(字节)blksize_t st_blksize;     // 文件系统的块大小blkcnt_t  st_blocks;      // 分配给文件的块数time_t    st_atime;       // 文件的最后访问时间time_t    st_mtime;       // 文件的最后修改时间time_t    st_ctime;       // 文件的最后状态改变时间
};

6.2 函数示例

下面是一个使用stat()函数的示例:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>int main() {const char *pathname = "example.txt";struct stat file_info;// 获取文件信息int ret = stat(pathname, &file_info);if (ret == -1) {perror("stat");return errno;}// 打印文件信息printf("File Size: %ld bytes\n", file_info.st_size);printf("File Permissions: %o\n", file_info.st_mode & 0777);printf("File Owner UID: %d\n", file_info.st_uid);printf("File Owner GID: %d\n", file_info.st_gid);return 0;
}

6.3 代码解释

在上述示例中,我们首先定义了一个文件路径pathname和一个struct stat结构体file_info,用于存储获取到的文件信息。

然后,我们使用stat()函数将文件信息存储到file_info结构体中。我们将文件路径和file_info结构体指针作为参数传递给stat()函数。如果获取文件信息失败,我们使用perror()函数打印错误信息,并返回errno变量。

最后,我们使用printf()函数打印获取到的文件信息,包括文件大小、文件权限、文件所有者的UIDGID等。

需要注意的是,stat()函数只能获取文件的信息,而不能修改文件的信息。如果需要修改文件的信息,可以使用chmod()函数来修改文件的权限。

7. fcntl()

7.1 原型、参数及返回值说明

7.1.1 原型:

fcntl()函数是Linux系统编程中用于对文件描述符进行控制操作的函数。它可以用于设置文件状态标志、获取文件状态标志、设置文件锁等。

fcntl()函数的原型如下:

#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );

7.1.2 参数:

  • fd:文件描述符,可以是打开文件的文件描述符,也可以是套接字的文件描述符。
  • cmd:控制命令,用于指定要执行的操作。
  • arg:可选参数,用于传递特定操作的参数。

7.1.3 返回值:

  • 成功:根据不同的操作命令返回不同的值,一般为0或一个正整数。
  • 失败:返回-1,并设置errno变量来指示错误类型。

下面是fcntl()函数的一些常用命令:

  • F_DUPFD:复制文件描述符,创建一个新的文件描述符,该描述符与原始描述符指向相同的打开文件。
  • F_GETFD:获取文件描述符的文件状态标志。
  • F_SETFD:设置文件描述符的文件状态标志。
  • F_GETFL:获取文件的打开方式和状态标志。
  • F_SETFL:设置文件的打开方式和状态标志。
  • F_GETLK:获取文件锁的信息。
  • F_SETLK:设置文件锁。
  • F_SETLKW:设置文件锁,如果无法获取锁,则阻塞等待。

7.2 函数示例

下面是一个使用fcntl()函数的示例:

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>int main() {int fd = open("example.txt", O_RDWR);if (fd == -1) {perror("open");return errno;}// 获取文件的打开方式和状态标志int flags = fcntl(fd, F_GETFL);if (flags == -1) {perror("fcntl");return errno;}// 设置文件的状态标志为非阻塞flags |= O_NONBLOCK;int ret = fcntl(fd, F_SETFL, flags);if (ret == -1) {perror("fcntl");return errno;}// 关闭文件描述符close(fd);return 0;
}

7.3 代码解释

在上述示例中,我们首先使用open()函数打开一个文件,并将返回的文件描述符存储在变量fd中。如果打开文件失败,我们使用perror()函数打印错误信息,并返回errno变量。

然后,我们使用fcntl()函数获取文件的打开方式和状态标志。将文件描述符和F_GETFL命令作为参数传递给fcntl()函数,获取到的文件状态标志存储在变量flags中。如果获取文件状态标志失败,我们同样使用perror()函数打印错误信息,并返回errno变量。

接下来,我们将文件的状态标志设置为非阻塞,通过将O_NONBLOCK标志位与flags进行按位或操作。然后,我们使用fcntl()函数将修改后的状态标志设置回文件描述符。将文件描述符、F_SETFL命令和修改后的状态标志作为参数传递给fcntl()函数。如果设置文件状态标志失败,我们同样使用perror()函数打印错误信息,并返回errno变量。

最后,我们使用close()函数关闭文件描述符,释放资源。

需要注意的是,fcntl()函数的使用非常灵活,可以根据需要进行各种操作,如复制文件描述符、获取文件锁等。在使用fcntl()函数时,需要注意错误处理,并确保文件描述符的有效性。同时,需要在不再需要使用文件描述符时及时关闭文件描述符,以释放资源并避免资源泄漏。

总结

文件IO操作是Linux系统编程中的重要部分。通过open()close()read()write()等函数,我们可以对文件进行打开、读取和写入操作。通过lseek()函数,我们可以在文件中进行定位。而通过stat()fcntl()dup()等函数,我们可以获取文件的状态信息,对文件描述符进行控制操作,复制文件描述符等。

除了上述的函数,还有许多其他的函数可以用于文件IO操作,如mkdir()用于创建目录,rmdir()用于删除目录,unlink()用于删除文件,rename()用于重命名文件等。

http://www.lryc.cn/news/126083.html

相关文章:

  • Ubuntu和centos版本有哪些区别
  • Netty:ChannelHandler抛出异常,对应的channel被关闭
  • pytest结合 allure 打标记之的详细使用
  • 【linux】2 软件管理器yum和编辑器vim
  • Angular中的ActivatedRoute和Router
  • Layui精简版,快速入门
  • SSH远程Ubuntu教程
  • NPM与外部服务的集成(下)
  • Flask Web开发实战(狼书)| 笔记第1、2章
  • PHP利用PCRE回溯次数限制绕过某些安全限制实战案例
  • 读书笔记 |【项目思维与管理】➾ 顺势而动
  • 开发利器:接口代理和接口模拟工具
  • MAVEN利器:一文带你了解MAVEN以及如何配置
  • 解决 adb install 错误INSTALL_FAILED_UPDATE_INCOMPATIBLE
  • 学习Vue:Event Bus 与 Provide/Inject
  • Java 工具类之JSON key根据ASCII排序
  • 深兰科技提出新多模态谣言监测模型,刷新世界纪录
  • 【从零学习python 】33.装饰器的作用(二)
  • 【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)
  • 比ChatGPT更强的星火大模型V2版本发布!
  • Character Animation With Direct3D 读书笔记
  • SpringBoot之HandlerInterceptor拦截器的使用
  • 【共同缔造 情暖襄阳】 暑期关爱未成年人志愿服务活动合集(三)
  • 私密相册管家-加密码保护私人相册照片安全
  • webpack 热更新的实现原理
  • OpenCV-Python中的图像处理-傅里叶变换
  • 阿里云FRP内网穿透挂载多台服务器
  • 多店铺功能
  • mysql主从复制搭建(一主一从)
  • 什么是Liquid UI?