Открытие gzipped файлы для чтения в C, не создавая временные файлы

См. сообщение Scott Hanselman при использовании DotNetOpenID в ASP.NET. блог Andrew Arnott полон образцов при использовании DotNetOpenID с ASP.NET, включая ASP.NET MVC.

я недавно поднял трубку DotNetOpenID для Подтекста 2,0 выпуска. Это пошло действительно гладко - примеры кода, включенные с загрузкой DotNetOpenID, довольно полезны. Одна вещь, которую я рекомендовал бы, состоит в том, что Вы просто пользуетесь библиотекой и избегаете управления ASP.NET. Это использует основанное на таблице расположение (hardcoded) и довольно трудно модернизировать.

8
задан Switch 30 November 2009 в 14:28
поделиться

4 ответа

Вы можете использовать libzlib, чтобы напрямую открывать сжатые файлы.

Он также предлагает функцию "gzopen", которая ведет себя аналогично fopen, но работает с файлами, сжатыми gzip. Однако fscanf, вероятно, не будет работать с таким дескриптором, поскольку ожидает обычных указателей FILE.

6
ответ дан 5 December 2019 в 10:03
поделиться

Вы можете использовать zlib , но это потребует от вас замены вызовов ввода-вывода, чтобы они были специфичными для zlib.

0
ответ дан 5 December 2019 в 10:03
поделиться

Если popen - честная игра, вы можете сделать это с помощью fopen и fscanf :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
  const char prefix[] = "zcat ";
  const char *arg;
  char *cmd;
  FILE *in;
  char buf[4096];

  if (argc != 2) {
    fprintf(stderr, "Usage: %s file\n", argv[0]);
    return 1;
  }

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

  sprintf(cmd, "%s%s", prefix, arg);

  in = popen(cmd, "r");
  if (!in) {
    fprintf(stderr, "%s: popen: %s\n", argv[0], strerror(errno));
    return 1;
  }

  while (fscanf(in, "%s", buf) == 1)
    printf("%s: got [%s]\n", argv[0], buf);

  if (ferror(in)) {
    fprintf(stderr, "%s: fread: %s\n", argv[0], strerror(errno));
    return 1;
  }
  else if (!feof(in)) {
    fprintf(stderr, "%s: %s: unconsumed input\n", argv[0], argv[1]);
    return 1;
  }

  return 0;
}

Например:

$ zcat file.gz
Every good boy does fine.
$ ./gzread file.gz
./gzread: got [Every]
./gzread: got [good]
./gzread: got [boy]
./gzread: got [does]
./gzread: got [fine.]
6
ответ дан 5 December 2019 в 10:03
поделиться

для этого вам нужно открыть канал. Базовый поток в псевдокоде:

create pipe // man pipe

fork // man fork

if (parent) {
    close the writing end of the pipe // man 2 close
    read from the pipe // man 2 read
} else if (child) {
    close the reading end of the pipe // man 2 close
    overwrite the file descriptor for stdout with the writing end of the pipe // man dup2 
    call exec() with gzip and the relevant parameters // man 3 exec
}

Вы можете использовать man страницы в комментариях для получения более подробной информации о том, как это сделать.

0
ответ дан 5 December 2019 в 10:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: