2016-12-01 4 views
0

Я пытаюсь прочитать двоичные данные через stdin (0) в мою программу, используя команду cat. Задачей моей программы является изменение двоичного кода на целое или двойное и запись в требуемый дескриптор файла.

Когда я запустил команду: cat data_int.bin | ./myprogram -d, я ничего не могу прочитать, а также размер ввода равен 0. Но когда я пытаюсь: ./myprogram -d -I 0 0<data_int.bin, моя программа может читать байты и успешно заканчивать.


Мой код:
Чтение двоичных данных через stdin с командой cat в linux

#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

Связанный: [UNIX/Linux IPC: чтение из трубы. Как узнать длину данных во время выполнения?] (Http://stackoverflow.com/questions/1151029/unix-linux-ipc-reading-from-a-pipe-how-to-know-length-of-data-at -runtime) –

ответ

1

Трубы всегда st_size 0, так как длина потока байтов, которые будут записаны в трубу, не известно заранее.

Существует множество программ, которые ведут себя по-разному на cat foo | prog и prog < foo. Это причина. Во втором случае prog имеет обычный файл на stdin, поэтому stat раскрывает размер. Также во втором случае будет работать lseek/fseek, а на трубе этого не произойдет.

Если вы хотите прочитать содержимое stdin в буфере, и вам нужно, чтобы он работал, когда stdin является каналом, вы должны угадать размер для него, а затем отслеживать, сколько вы читаете и когда вы исчерпали память, выделите еще несколько. realloc подходит для этого.

+0

Я изменил размер буфера на 20 и прочитал nbytes до 20. все равно, я ничего не получаю ... 20 - это полный размер двоичного файла. –

+0

@domenkavran Что означает «читать nbytes до 20»? –

+0

ssize_t read (int fildes, void * buf, size_t nbyte) - Я установил nbyte на 20 и размер буфера в буфер [20]. –

Смежные вопросы