zlib gzwrite не записывает весь файл C - PullRequest
0 голосов
/ 02 мая 2020

В настоящее время я пытаюсь передать файл .tar.gz с сервера на клиент через сокеты в C, но я сталкиваюсь с ошибкой при чтении из tar.gz с помощью gzopen + gzread и записи его в новом файле tar.gz с gzwrite происходит сбой, в результате получается файл tar.gz, который поврежден и даже не совпадает с размером оригинала.

Сначала я подумал, что это как-то связано с моим сокетом logi c, но я проверил его в меньшем масштабе и просто прочитал и сразу же записал его в тот же каталог, и даже после этого ошибка сохраняется. Ниже приведен пример кода, демонстрирующего эту проблему:

gzFile gz = gzopen("tar.tar.gz", "r");
// tar.tar contains one text file, tarred with "tar -cvf tar.tar text.txt"
// tar.tar.gz created with "gzip tar.tar"
struct stat st;
stat("tar.tar.gz", &st);  // get size
unsigned int gz_buffer_size = st.st_size;
printf(".gz size: %d\n", gz_buffer_size);
unsigned char *gz_buffer = malloc(gz_buffer_size);
gzread(gz, buffer, buffer_size);
gzclose(gz);

gzFile test = gzopen("test.tar.gz", "w");
printf("wrote to test: %d\n", gzwrite(test, gz_buffer, gz_buffer_size));
gzclose(test);

После выполнения вышеизложенного программа выводит на стандартный вывод, что размер моего .gz составляет 169 байт, и даже печатает gzwrite, который записал в 169 байт новый файл .gz. Так почему же тогда, когда я запускаю stat -c %s test.tar.gz, я получаю, что размер test.tar.gz равен 24?

1 Ответ

1 голос
/ 02 мая 2020

Несколько вещей здесь:

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

  • Вы полностью игнорируете * 1014 Возвращаемое значение *, поэтому вы не знаете, сколько фактически было прочитано байтов.

  • Вы читаете в buffer и пишете gz_buffer, который не инициализирован.

  • Затем вы сжимаете и записываете эту неинициализированную память в другой файл. gzwrite() возвращает количество сжатых байтов, а не длину сжатого фрагмента (чего он не может знать из-за таких вещей, как блоки, заполнение и т. Д. c., Которые зависят от будущих записей, если таковые имеются). Не исключено, что 169 несжатых байтов уменьшаются до 24 сжатых байтов.

  • Вы не проверяете ошибки; все ваши функции должны иметь проверки, чтобы убедиться в их успешности, прежде чем делать что-либо с тем, что они возвращают / устанавливают.

...