【问题标题】:How to not write more bytes than are in the buffer in C?如何在 C 中写入的字节数不超过缓冲区中的字节数?
【发布时间】:2020-05-31 20:35:36
【问题描述】:

我正在尝试编写一个简单的复制程序。它以 100 个字节为单位读取 test_data.txt,并将这些字节复制到 test_dest.txt。我发现目标文件至少比源文件大一个单位chunk。我如何调整它以便复制正确数量的字节?我需要大小为 1 的复制缓冲区吗? 请注意,重点是使用低级 I/O 系统调用来解决它。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

int main() { 

    int fh  = open("test_data.txt", O_RDONLY);
    int trg = open("test_dest.txt", O_CREAT | O_WRONLY);

    int  BUF_SIZE = 100;
    char inp[BUF_SIZE]; 

    int read_bytes = read(fh, inp, BUF_SIZE);
    while (read_bytes > 0) {
        write(trg, inp, BUF_SIZE);
        read_bytes = read(fh, inp, BUF_SIZE);
    }   

    close(trg);
    close(fh);
    return 0;
}

【问题讨论】:

    标签: c


    【解决方案1】:

    read 函数只是告诉你它读取了多少字节。你应该write那个字节数:

    write(trg, inp, read_bytes);
    

    另一方面,您真的应该检查write 调用中的故障。绝对是open 电话。

    另外一点,您只需要一个致电read

    ssize_t read_bytes;  // The read function is specified by POSIX to return a ssize_t
    while ((read_bytes = read(fh, inp, sizeof inp)) > 0)
    {
        write(trg, inp, read_bytes);
    }
    

    【讨论】:

    • 目前正在尝试正确处理基本的 I/O,但感谢您的强调。
    【解决方案2】:

    您的代码不是标准的 C11。通过阅读标准n1570 进行检查,并在Modern C 书籍之前阅读。

    您的代码或多或少是POSIX,并且肯定可以在大多数 Linux 发行版上编译,例如DebianUbuntu(你想安装他们的 build-essentials 元包)。

    请阅读open(2)、read(2)write(2)、您正在使用的每个syscalls(2) 以及errno(3) 的文档

    请注意,您调用的每个函数都可能失败,您的代码应测试失败情况。另请注意,write(或read)在某些情况下可能是不完整的,这已记录在案。

    建议:

    使用最近的 GCC - 大多数 Linux 发行版上常用的 C 编译器,编译 with 所有警告和调试信息,所以 gcc -Wall -Wextra -g

    阅读Advanced Linux ProgrammingHow to debug small programs

    学习use the GDB debugger

    了解build automation 工具,例如GNU make(大多数Linux 系统上非常常见的工具)或ninja

    注意strace(1)。你可以在cp(1)上使用它,或者研究GNU coreutils的源码(提供cp)。

    请记住,大多数 Linux 发行版主要由 open source 软件组成

    你可以研究他们的源代码。

    我什至认为你应该研究他们的源代码,至少是为了获得灵感!

    我正在尝试编写一个简单的复制程序。它以 100 字节为单位读取 test_data.txt 并将这些字节复制到 test_dest.txt

    如果性能很重要,那么 100 字节的块大小在实践中确实太小了。我会推荐两个大于 4Kbytes 的幂(x86-64 上通常的 page 大小)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      相关资源
      最近更新 更多