【发布时间】:2012-04-03 12:59:54
【问题描述】:
我的 C/C++ 程序从命令行获取一个文件作为参数。从“常规文件”读取数据没有问题/一般编程任务,但是当文件来自“设备管道”例如 /dev/fd/63 时,它会导致我的程序崩溃。
复制:
从您友好的社区 bash shell 中,将“设备管道”作为文件提供给您的应用程序。您的应用应尝试将文件内容读入缓冲区。
./yourapp
注意上面的命令没有重定向应用程序的标准输入,这不是预期的结果..
我认为很多人都不知道这会使他们的应用程序崩溃。 Gnome 项目中的应用程序“种子”使用 glib 进行 I/O,但它可以很好地从这些文件中读取。命令“cat”也可以优雅地处理这种情况。为什么当我尝试像普通文件一样读取命名管道的内容时,我的应用程序会出现崩溃错误?
编辑:相关代码部分
#include <stdio.h>
int main(int argc, char **argv) {
FILE *file;
char *buffer;
unsigned long fileLen;
//Open file
file = fopen(argv[1], "rb");
if (!file) return -1;
//Get file length
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
fseek(file, 0, SEEK_SET);
//Allocate memory
buffer=(char *)malloc(fileLen+1);
if (!buffer){
fprintf(stderr, "Memory error!");
fclose(file);
return -2;
}
//Read file contents into buffer
fread(buffer, fileLen, 1, file);
fclose(file);
fprintf(stdout, "Size: %i", fileLen);
free(buffer);
}
【问题讨论】:
-
我认为可能有问题。
-
什么错误或崩溃?您是否尝试过在调试器中运行程序以查看错误在哪里?
-
如代码所示,问题在于 fileLen 为 -1!代码没有检查这一点,我的程序后来继续使用产生段错误的“缓冲区”进行操作。对不起。我还不是一个好的 c 程序员,所以这对我来说并不是很明显。没有愚蠢的问题,只有愚蠢的答案!
-
考虑到您可能从管道中获取的数据可能比您一次在内存中所能容纳的更多,您应该重新考虑尝试一次将整个“文件”读入内存的方法。
-
@evilotto 对我来说很有意义。但是我没有写原始代码。并且原始代码显然没有考虑从命名管道中读取。所以我是对的,很多程序都没有为这种情况做好准备。