【问题标题】:Low-level C I/O: When read from one file and write to another I'm hitting an infinite loop低级 C I/O:从一个文件读取并写入另一个文件时,我遇到了无限循环
【发布时间】:2012-03-19 00:35:51
【问题描述】:

我正在处理一项只允许使用低级 I/O(read()、write()、lseek())以及 perror() 的作业。

我已经能够以正确的权限打开 nessisary in 和 out 文件,但是当我输出时,我得到了 in 文件内容的无限循环。见下面的 sn-p...

void *buf = malloc(1024);
while((n = read(in, buf, 1024)) > 0){
    if(lseek(in, n, SEEK_CUR) == -1){
        perror("in file not seekable");
        exit(-1);
    }
    while((m = write(out, buf, n)) > 0){
        if(lseek(out, m, SEEK_CUR) == -1){
            perror("out file not seekable");
            exit(-1);
        }
    }
    if(m == -1){ perror("error writing out"); exit(-1); }
}
if(n == -1){ perror("error reading in"); exit(-1); }

我已经从我的代码中删除了一些错误捕获,您可以假设变量已初始化并且包含语句在那里。

【问题讨论】:

  • 到目前为止你做了哪些调试?例如,它卡在哪个循环中,外循环还是内循环?
  • 我认为你正在做的是重复写同一行。尝试将write 周围的while 更改为if
  • 卡在内部循环中。除此之外,我不能告诉你更多。
  • 谢谢大家!代码正在运行。

标签: c io low-level-io


【解决方案1】:

问题是内循环:

while((m = write(out, buf, n)) > 0){

应该是

if((m = write(out, buf, n)) > 0){

您只希望buf 被写入一次,而不是无限多次。您还需要处理的是短写入,即当 write 返回时 m 0。

另外,lseek() 调用是错误的,但它们不会导致循环。 read()write() 已经提前了当前文件偏移量。您不需要手动推进它,除非您想跳过输入或输出文件中的字节(请注意,在输出文件的情况下,在 UNIX 上,跳过字节可能会导致文件中出现所谓的“漏洞”,这些区域是零但不占用磁盘空间)。

【讨论】:

    【解决方案2】:

    你为什么在阅读后寻找输入文件?由于您最多会读取 1024 个字节(意思是 n 将介于 0 和 1024 之间),因此您将不断寻找超出输入文件指针的位置,以便您丢失 传输中的数据(包括当您接近结尾时可能超出文件末尾)。

    可能是导致无限循环的原因之一,但更阴险的原因是使用while 进行写入。由于这将在成功时返回大于零的值,因此您将不断地反复将第一个块写入文件。至少在您用完磁盘空间或其他资源之前。

    您也不需要在写入时使用seekreadwrite 调用做了他们必须做的事情为下一个 readwrite 正确地推进文件指针 - 这不是你必须手动做的事情。 p>

    您可能可以将整个事情简化为:

    while ((n = read (in, buf, 1024)) > 0) {
        if ((m = write (out, buf, n)) != n) {
            perror ("error writing out");
            exit (-1);
        }
    }
    

    具有以下优点:

    • 摆脱seek 调用;
    • 移除“无限”循环;
    • 检查您是否已写入所有请求的字节。

    【讨论】:

    • 在给定 SEEK_CUR 的来源值的情况下,lseek 不会将文件中的当前位置增加 n 吗?
    • 没错,这就是为什么 lseek() 调用不会导致循环,它们只会导致跳过字节。
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 2021-01-23
    • 1970-01-01
    • 2013-11-09
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多