linux系统文件io,及与标准io区别

Linux 系统中的文件 I/O(输入/输出)涉及多种操作和系统调用,用于读写文件和管理文件描述符。

文件 I/O 基础

**1. 文件描述符(File Descriptors):

  • 文件描述符是非负整数,用于标识一个已打开的文件、设备或管道。
  • 文件描述符 0、1 和 2 分别表示标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。**

**2. 文件 I/O 操作:

  • 文件 I/O 包括打开、关闭、读取、写入和管理文件。**

常用系统调用

  1. open:
  • 用于打开文件或设备,并返回一个文件描述符。

  • 原型: `int open(const char *pathname, int flags, mode_t mode);`

  • 示例:

int fd = open("example.txt", O_RDONLY);

  1. close:
  • 关闭一个打开的文件描述符。

  • 原型: `int close(int fd);`

  • 示例:

close(fd);

  1. read:
  • 从文件描述符中读取数据。

  • 原型: `ssize_t read(int fd, void *buf, size_t count);`

  • 示例:

char buffer[100];

ssize_t bytesRead = read(fd, buffer, sizeof(buffer));

  1. write:
  • 向文件描述符写入数据。

  • 原型: `ssize_t write(int fd, const void *buf, size_t count);`

  • 示例:

const char *msg = "Hello, World!";

ssize_t bytesWritten = write(fd, msg, strlen(msg));

  1. lseek:
  • 设置或获取文件描述符的偏移量。

  • 原型: `off_t lseek(int fd, off_t offset, int whence);`

  • 示例:

off_t newPos = lseek(fd, 0, SEEK_END);

  1. ftruncate:
  • 截断文件到指定长度。

  • 原型: `int ftruncate(int fd, off_t length);`

  • 示例:

ftruncate(fd, 1024);

  1. fopen, fclose, fread, fwrite:
  • 标准 C 库函数,用于文件操作,提供更高级的文件 I/O。

  • 示例:

FILE *file = fopen("example.txt", "r");

char buffer[100];

fread(buffer, sizeof(char), 100, file);

fclose(file);

文件 I/O 操作示例

  1. 打开文件并读取数据

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

int main() {

int fd = open("example.txt", O_RDONLY);

if (fd < 0) {

perror("open");

return 1;

}

char buffer[100];

ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);

if (bytesRead < 0) {

perror("read");

close(fd);

return 1;

}

buffer[bytesRead] = '\0'; // Null-terminate the buffer

printf("Read data: %s\n", buffer);

close(fd);

return 0;

}

  1. 写入文件

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

int main() {

int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);

if (fd < 0) {

perror("open");

return 1;

}

const char *msg = "Hello, World!";

ssize_t bytesWritten = write(fd, msg, strlen(msg));

if (bytesWritten < 0) {

perror("write");

close(fd);

return 1;

}

close(fd);

return 0;

}

高级文件 I/O 操作

  1. mmap:
  • 将文件或设备映射到内存,以实现更高效的 I/O 操作。

  • 原型: `void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);`

  • 示例:

#include <sys/mman.h>

#include <fcntl.h>

int fd = open("example.txt", O_RDONLY);

off_t length = lseek(fd, 0, SEEK_END);

void *mapped = mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0);

if (mapped == MAP_FAILED) {

perror("mmap");

close(fd);

return 1;

}

// Use mapped memory...

munmap(mapped, length);

close(fd);

  1. ioctl:
  • 执行设备特定的输入/输出控制操作。

  • 原型: `int ioctl(int fd, unsigned long request, ...);`

  • 示例:

#include <sys/ioctl.h>

int fd = open("/dev/some_device", O_RDWR);

int result = ioctl(fd, SOME_IOCTL_COMMAND, &parameter);

文件 I/O 的注意事项

**1. 错误处理:

  • 总是检查系统调用的返回值,处理错误并打印适当的错误信息。**

**2. 资源管理:

  • 确保文件描述符在完成操作后被关闭,以防资源泄漏。**

**3. 文件权限:

  • 使用 open 时指定正确的权限,并确保程序有权访问指定的文件或设备。**

**4. 同步和缓存:

  • 文件 I/O 操作可能涉及缓存和同步操作,了解 fsync 和 fdatasync 等函数可以帮助确保数据被正确写入磁盘。**

在 C 语言中,文件 I/O 和标准 I/O 是两种不同的输入/输出操作方式,各自有不同的接口和功能。

文件 I/O(系统调用)

文件 I/O 是基于系统调用的低级 I/O 操作方式,直接与操作系统交互。

主要函数

  1. open: 打开一个文件,返回文件描述符。

int fd = open(const char *pathname, int flags, mode_t mode);

  1. close: 关闭一个文件描述符。

int close(int fd);

  1. read: 从文件描述符中读取数据。

ssize_t read(int fd, void *buf, size_t count);

  1. write: 向文件描述符写入数据。

ssize_t write(int fd, const void *buf, size_t count);

  1. lseek: 设置或获取文件描述符的偏移量。

off_t lseek(int fd, off_t offset, int whence);

  1. ftruncate: 截断文件到指定长度。

int ftruncate(int fd, off_t length);

特点

**- 低级操作: 直接操作文件描述符,提供对文件的原始访问。

  • 无缓冲: 直接与内核交互,通常需要手动管理缓存和同步。
  • 灵活性: 可以用于处理各种设备(如管道、网络套接字)和文件类型。
  • 效率: 可以进行高效的 I/O 操作,尤其是在处理大文件时。**

标准 I/O(C 标准库)

标准 I/O 是 C 标准库提供的高级 I/O 操作方式,基于文件流的抽象。

主要函数

  1. fopen: 打开一个文件流。

FILE *fopen(const char *filename, const char *mode);

  1. fclose: 关闭一个文件流。

int fclose(FILE *stream);

  1. fread: 从文件流中读取数据。

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

  1. fwrite: 向文件流写入数据。

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

  1. fseek: 设置文件流的读写位置。

int fseek(FILE *stream, long offset, int whence);

  1. ftell: 获取文件流的当前读写位置。

long ftell(FILE *stream);

  1. fprintf`/`fscanf: 格式化写入/读取。

int fprintf(FILE *stream, const char *format, ...);

int fscanf(FILE *stream, const char *format, ...);

特点

**- 高级抽象: 提供对文件的更高层次的抽象,操作文件流而不是文件描述符。

  • 缓冲: 内置缓冲机制(如 `FILE` 结构),通常提供更高的性能和易用性。
  • 便利性: 更易于使用,适合大多数文件处理任务。
  • 安全性: 自动处理缓冲区、格式化等,减少了许多底层错误的可能性。**

比较

**1. 级别:

  • 文件 I/O: 低级操作,直接操作文件描述符。
  • 标准 I/O: 高级操作,基于文件流的抽象。**

**2. 缓冲:

  • 文件 I/O: 不自动缓冲,需要手动管理。
  • 标准 I/O: 自动缓冲,通常更高效。**

**3. 易用性:

  • 文件 I/O: 更复杂,适合需要精细控制的情况。
  • 标准 I/O: 更简单,适合大多数应用程序。**

**4. 性能:

  • 文件 I/O: 在需要低级控制或处理大量数据时可能更高效。
  • 标准 I/O: 对于大多数普通操作,性能通常足够,并且提供了额外的便利性。**

**5. 灵活性:

  • 文件 I/O: 可以操作各种文件和设备类型,如管道、套接字等。
  • 标准 I/O: 主要用于文件操作,虽然可以与标准输入输出设备一起使用,但不适用于所有类型的设备。**

示例代码

文件 I/O 示例:

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

int main() {

int fd = open("example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);

if (fd == -1) {

perror("open");

return 1;

}

const char *msg = "Hello, World!";

write(fd, msg, strlen(msg));

close(fd);

return 0;

}

标准 I/O 示例:

#include <stdio.h>

int main() {

FILE *file = fopen("example.txt", "w");

if (file == NULL) {

perror("fopen");

return 1;

}

fprintf(file, "Hello, World!");

fclose(file);

return 0;

}

总结来说,文件 I/O 和标准 I/O 各有优缺点,根据需要选择合适的方式进行文件操作。如果你需要更底层的控制或者处理特殊设备,文件 I/O 更合适;而对于大多数常规的文件操作,标准 I/O 更加方便和高效。

相关推荐
燕雀安知鸿鹄之志哉.5 分钟前
攻防世界 web ics-06
网络·经验分享·安全·web安全·网络安全
wanhengidc26 分钟前
短视频运营行业该如何选择服务器?
运维·服务器
雨中rain40 分钟前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
ProcessOn官方账号44 分钟前
如何绘制网络拓扑图?附详细分类解说和用户案例!
网络·职场和发展·流程图·拓扑学
Bessssss1 小时前
centos日志管理,xiao整理
linux·运维·centos
s_yellowfish1 小时前
Linux服务器pm2 运行chatgpt-on-wechat,搭建微信群ai机器人
linux·服务器·chatgpt
豆是浪个1 小时前
Linux(Centos 7.6)yum源配置
linux·运维·centos
vvw&1 小时前
如何在 Ubuntu 22.04 上安装 Ansible 教程
linux·运维·服务器·ubuntu·开源·ansible·devops
我一定会有钱1 小时前
【linux】NFS实验
linux·服务器
王铁柱子哟-1 小时前
解决 正在下载VS Code 服务器... 问题
运维·服务器