在linux上用cat命令通过stdin读取二进制数据

时间:2016-12-01 18:29:49

标签: linux bash

我正在尝试使用cat命令通过stdin(0)将二进制数据读取到我的程序中。我的程序的任务是将二进制更改为整数或双精度并将其写入所需的文件描述符。

当我运行命令:cat data_int.bin | ./myprogram -d时,我无法读取任何内容,输入的大小也是0.但是当我尝试:./myprogram -d -I 0 0<data_int.bin时,我的程序可以读取字节并成功完成。


我的代码:

#libraries

int main(int argc, char* argv[]) {

        int c;
        extern char *optarg;
        extern int optind;
        extern int optopt;

        char input_file[100] = { 0 };
        int nastavljen_input = 0;
        char output_file[100] = { 0 };
        int nastavljen_output = 0;
        int tip = -1; // 0 - char, 1- int, 2 - double
        int fd_in = 0;
        int fd_out = 1;
        while((c = getopt(argc,argv, ":o:i:O:I:cdf")) != -1) {
            switch(c) {
                case 'o':
                    strcpy(output_file,optarg);
                    nastavljen_output = 1;
                    fd_out = open(output_file,O_WRONLY);
                    break;
                case 'i':
                    strcpy(input_file,optarg);
                    nastavljen_input = 1;
                    fd_in = open(input_file,O_RDONLY);
                    break;
                case 'O':
                    fd_out = atoi(optarg);
                    break;
                case 'I':
                    fd_in = atoi(optarg);
                    break;
                case 'c':
                    tip = 0;
                    break;
                case 'd':
                    tip = 1;
                    break;
                case 'f':
                    tip = 2;
                    break;
            }
        }

        if(tip > -1) {
            struct stat st;
            fstat(fd_in, &st); //fd_in would be 0 with cat command
            int size = st.st_size; // number of bytes in input file
            printf("%d\n",size); // this will print out 0 with cat command

            unsigned char buffer[size];
            read(fd_in,buffer,size);

            ...code continues...



标志-d用于读取表示整数的字节,-I用于选择输入文件描述符。在这种情况下,输出为stdout(1)。

我的问题是,我的代码存在问题,或者这只是cat命令的工作方式?我正在使用Xubuntu。

感谢您的时间和精力,
Domen

1 个答案:

答案 0 :(得分:1)

管道始终具有st_size 0,因为将要提前写入将要写入管道的字节流的长度。

有很多程序在cat foo | progprog < foo上的行为方式不同。这就是原因。在第二种情况下,prog在stdin上有一个常规文件,因此stat显示大小。同样在第二种情况下,lseek / fseek将起作用,而在管道上则不起作用。

如果你想将stdin的内容读入缓冲区,并且你需要在stdin是一个管道时工作,你必须猜测它的大小,然后跟踪你读了多少以及你什么时候耗尽内存,分配更多。 realloc对此有好处。