低级C I / O:当从一个文件读取并写入另一个文件时,我正在进行无限循环

时间:2012-03-19 00:35:52

标签: c io low-level-io

我正在进行一项只允许使用低级I / O(read(),write(),lseek())以及perror()的赋值。

我已经能够以正确的权限打开nessisary in和out文件,但是当我输出时,我得到一个无限循环的in文件内容。请参阅下面的代码段...

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

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

2 个答案:

答案 0 :(得分:2)

问题是内循环:

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

应该是

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

您只需要编写buf一次,而不是无限次。你还需要处理的是短写,即当写回来时m< n&& m> 0

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

答案 1 :(得分:0)

为什么您在阅读后在输入文件上寻找?因为你最多会读取1024个字节(意味着n将介于0到1024之间),你将不断寻找超出你离开输入文件指针的位置以便你将丢失传输中的数据(包括可能超出文件末尾的数据)。

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

您也不需要写seekreadwrite调用执行的操作正确地为下一个readwrite推进文件指针 - 这不是你必须手动完成。

你可以简化整个过程:

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

具有以下优点:

  • 摆脱seek来电;
  • 删除'无限'循环;
  • 检查您是否已写入所有所请求的字节。