You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用C语言低级IO调用(read、write、open)反向读取文件

仅用open、read、write反向读取文件的实现方法

核心思路

反向读取的关键是通过文件指针偏移从文件末尾开始,分段读取内容后输出。我们会用到系统调用open、read、write,以及lseek(不属于f开头的标准库函数,符合要求)来控制文件指针位置——毕竟要反向读,总得能调整指针位置才行。

具体步骤

  • 打开文件:用open函数以只读模式打开目标文件,获取文件描述符。要注意处理打开失败的情况,比如文件不存在或者权限不足。
  • 获取文件大小:通过lseek将文件指针移到文件末尾,返回值就是文件的总字节数。
  • 反向分段读取:从文件末尾开始,每次向前移动固定长度的偏移量(比如用1024字节的缓冲区),读取对应位置的内容,再用write输出到标准输出或目标文件。
  • 处理边界:当剩余字节不足缓冲区大小时,读取剩余的字节数,避免读取无效内容。

代码示例

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        write(STDERR_FILENO, "Usage: ./reverse_read <filename>\n", 31);
        exit(1);
    }

    // 打开文件,只读模式
    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        write(STDERR_FILENO, "Failed to open file\n", 19);
        exit(1);
    }

    // 获取文件大小:将指针移到末尾,返回值就是总字节数
    off_t file_size = lseek(fd, 0, SEEK_END);
    if (file_size == -1) {
        write(STDERR_FILENO, "Failed to get file size\n", 22);
        close(fd);
        exit(1);
    }

    char buf[1024];
    off_t current_pos = file_size;
    ssize_t bytes_read;

    // 从末尾开始反向读取
    while (current_pos > 0) {
        // 计算本次要读取的字节数:如果剩余字节小于缓冲区大小,就读剩余的
        size_t read_size = (current_pos > sizeof(buf)) ? sizeof(buf) : current_pos;
        // 将指针移到要读取的起始位置:current_pos - read_size
        if (lseek(fd, current_pos - read_size, SEEK_SET) == -1) {
            write(STDERR_FILENO, "Failed to seek file\n", 19);
            close(fd);
            exit(1);
        }
        // 读取内容到缓冲区
        bytes_read = read(fd, buf, read_size);
        if (bytes_read == -1) {
            write(STDERR_FILENO, "Failed to read file\n", 19);
            close(fd);
            exit(1);
        }
        // 写入到标准输出
        write(STDOUT_FILENO, buf, bytes_read);
        // 更新当前位置
        current_pos -= bytes_read;
    }

    close(fd);
    return 0;
}

关键细节说明

  • 文件描述符:open返回的整数是系统级的文件标识,和标准库的FILE*指针不是一回事。
  • lseek的作用:lseek(fd, offset, whence)用来移动文件指针,SEEK_END表示从文件末尾开始计算偏移,SEEK_SET表示从文件开头计算。
  • 缓冲区大小:示例中用1024字节的缓冲区,你可以根据需求调整,平衡效率和内存占用。
  • 错误处理:每个系统调用都要检查返回值,避免出现文件打开失败、读取失败等异常情况。

内容的提问来源于stack exchange,提问作者Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:30:52