2015-04-17 3 views
0

Я новичок в программировании на языке C. Я использую библиотеку, которая требует файлового дескриптора из источника байтового потока. Он работает отлично, когда у меня есть обычные файлы. Тем не менее, у меня есть ввод информации о файлах gz. Общий объем сжатых данных, которые мне нужны для разбора, составляет около 5 ТБ. У меня не хватает места, чтобы распаковать их все.Как получить читаемый файловый дескриптор из источника байтового потока из сжатых файлов (gz)

Я использовал следующие два метода, но они не кажется, работает,

input = gzopen (argv[i], "r"); 

Второй метод.

arg = argv[1]; 
    cmd = malloc(sizeof(prefix) + strlen(arg) + 1); 
    if (!cmd) { 
     fprintf(stderr, "%s: malloc: %s\n", argv[i], strerror(errno)); 
     return 1; 
    } 
    sprintf(cmd, "%s%s", prefix, arg); 
    input = popen(cmd, "r"); 

Я был бы признателен, если может быть предоставлена ​​помощь.

Заранее спасибо.

+1

«... они, похоже, не работают», требуется дополнительное разъяснение. Они не приводят к ошибкам, но не работают? Я также не понимаю, что должен был сделать пример «popen»: http://man7.org/linux/man-pages/man3/popen.3.html – usr2564301

+0

Большое вам спасибо за ваш ответ. Я получаю ошибку сегментации как исключение времени выполнения. Он работает со следующим методом в несжатом файле. fd = open (argv [i], O_RDONLY); Я передаю fd в библиотеку, и синтаксический анализ работает отлично. – user984201

+0

@ user984201 Не могли бы вы отправить полную программу, показывающую проблему, которую у вас есть? – fuz

ответ

1

Я выводя немного здесь, так как вы не показывают нам прототип библиотечной функции, которую вы используете, но вы говорите в комментарии, что это работает для вас, когда файл распаковывается:

fd = open(argv[i], O_RDONLY); 

но использование gzopen() или popen() нет. Поэтому я понимаю, что используемая вами функция библиотеки принимает аргумент дескриптора файла и считывает и интерпретирует сами данные.

Это приводит к тому, что должна быть ваша непосредственная проблема. Open() возвращает дескриптор файла «int», но gzopen() и popen() этого не делают.

Документация Zlib определяет gzopen() таким образом:

ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); 

Так что возвращает обычай 'gzFile' тип дескриптора файла; вы не можете передать это функции, которая планирует читать read(), ожидая дескриптор int файла.

Аналогичным образом, popen() возвращает дескриптор файла STILE FILE *, а не int kind, и передавая это тому, что ожидает, что int также не будет работать.

Итак, если вы хотите использовать zlib, вам придется использовать собственную функцию gzread(), а затем передать данные, которые вы читаете в библиотечную функцию, через дескриптор типа int, возможно, через канал. Это было бы громоздким.

Ваша лучшая ставка может быть использована с помощью popen(), как вы пытались, но используйте функцию stdio fileno(), чтобы получить дескриптор int, лежащий в основе FILE *, и передать его функции вашей библиотеки.

Так что, предполагая, что «префикс» в вашем исходном коде был чем-то вроде «gzip -dc», команда, которая передавала бы распакованные данные из вашего файла в stdout, мы могли бы изменить ваш код на что-то вроде этого (также вы назначили Arg значение 'ARGV [1], но используется "ARGV [я] elsewhere-- Я предполагаю,«1»была опечатка):

char *prefix, *arg, *cmd; 
    FILE *pinput; 
    int fd; 

    prefix = "gzip -dc "; 
    arg = argv[i]; 
    cmd = malloc(strlen(prefix) + strlen(arg) + 1); 
    if (!cmd) { 
     fprintf(stderr, "%s: malloc: %s\n", argv[i], strerror(errno)); 
     return 1; 
    } 
    sprintf(cmd, "%s%s", prefix, arg); 
    pinput = popen(cmd, "r"); 
    fd = fileno(pinput); 

Тогда вы должны быть в состоянии передать«Fd»в вашей библиотечной функции и работать так же, как и с несжатыми данными.

И не забудьте бесплатно (cmd), когда вы все закончите с этим!

+0

Это работает, отлично. У меня нет слов, чтобы поблагодарить вас за то, что вы не только опубликовали ответ, но и подробно объяснили его. Я очень благодарен вам. – user984201

+0

Рад, что я могу помочь! –

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

  • Нет связанных вопросов^_^