低级别的CI/O:当从一个文件读取并写入另一个我正在打一个无限循环
我正在处理一个只允许使用低级别I/O(读(),写( ),lseek())以及perror()。低级别的CI/O:当从一个文件读取并写入另一个我正在打一个无限循环
我已经能够打开具有正确权限的输入输出文件,但是当我输出时,我得到了文件内容的无限循环输出。请参见下面的一段:
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); }
我已删除了一些错误从我的代码捕获,你可以假设变量初始化,包括声明在那里。
问题是内部循环:
while((m = write(out, buf, n)) > 0){
确实应该
if((m = write(out, buf, n)) > 0){
你只想buf
被写入一次,而不是无限多次。你还需要处理很短写,也就是,当有m个写入返回<ň& & M> 0
此外,lseek()
电话是错的,但它们不会导致循环。 read()
和write()
已经提前当前的文件偏移量。除非要跳过输入或输出文件中的字节(注意在输出文件的情况下,在UNIX上,跳过字节可能会导致文件中出现所谓的“漏洞”,这些区域是零但不占用磁盘空间)。
为什么你在阅读后寻找输入文件?由于您最多可以读取1024个字节(意思是n
将介于0到1024之间),您将继续寻找超出您已经离开输入文件指针的地方,以便您将丢失中的数据转移(包括在您接近结束时可能超出文件末尾)。
这可能是一个原因,为什么你有一个无限循环,但更为阴险的是使用while
写入。由于这将在成功时返回大于零的值,因此您将不断将第一个块重复写入文件。至少在您耗尽磁盘空间或其他资源之前。
您也不需要写入seek
。 read
和write
呼叫做他们必须做的和为下一个read
或write
正确地提前文件指针 - 这不是你必须手动完成的。
你也许可以简化整个事情:
while ((n = read (in, buf, 1024)) > 0) {
if ((m = write (out, buf, n)) != n) {
perror ("error writing out");
exit (-1);
}
}
它的优点是:
- 摆脱
seek
通话; - 删除'无限'循环;
- 检查您是否写过全部请求的字节数。
考虑到SEEK_CUR的哪个值,会不会将文件中的当前位置增加n? – Dan 2012-03-19 00:41:29
准确地说,这就是lseek()调用不会导致循环的原因,它们只会导致跳过的字节。 – 2012-03-19 00:44:29
到目前为止,您已经完成了哪些调试?例如,哪个循环被卡住,外部循环还是内部循环? – 2012-03-19 00:38:55
我认为你在做的是重复写同一行。尝试将'write'周围的'while'改为'if' – twain249 2012-03-19 00:41:33
它卡在内部循环中。除此之外,我不能告诉你其他的事情。 – Dan 2012-03-19 00:43:12