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);
 

2. close:
   - 关闭一个打开的文件描述符。
   - 原型: `int close(int fd);`
   - 示例:

     close(fd);
 

3. read:
   - 从文件描述符中读取数据。
   - 原型: `ssize_t read(int fd, void *buf, size_t count);`
   - 示例:

     char buffer[100];
     ssize_t bytesRead = read(fd, buffer, sizeof(buffer));
 

4. 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));
 

5. lseek:
   - 设置或获取文件描述符的偏移量。
   - 原型: `off_t lseek(int fd, off_t offset, int whence);`
   - 示例:

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

6. ftruncate:
   - 截断文件到指定长度。
   - 原型: `int ftruncate(int fd, off_t length);`
   - 示例:

     ftruncate(fd, 1024);
 

7. 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
#include
#include

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;
}
 

2. 写入文件


#include
#include
#include

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
     #include

     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);
 

2. ioctl:
   - 执行设备特定的输入/输出控制操作。
   - 原型: `int ioctl(int fd, unsigned long request, ...);`
   - 示例:

     #include

     int fd = open("/dev/some_device", O_RDWR);
     int result = ioctl(fd, SOME_IOCTL_COMMAND, ¶meter);
 

文件 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);
 

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

   int close(int fd);
 

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

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

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

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

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

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

6. 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);
   

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

   int fclose(FILE *stream);
 

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

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

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

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

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

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

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

   long ftell(FILE *stream);
 

7. 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
#include
#include

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

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 更加方便和高效。

你可能感兴趣的:(linux,服务器,网络)