zlib gzwrite 不写入整个文件 C

zlib gzwrite not writing entire file C

我目前正在尝试通过 C 中的套接字将一个 .tar.gz 文件从服务器传输到客户端,但是我 运行 在从 tar.gz 使用 gzopen + gzread 并使用 gzwrite 将其写入新的 tar.gz 文件失败导致 tar.gz 文件损坏,甚至与原始文件大小不同。

起初我以为是我的套接字逻辑问题,但我在小范围内进行了测试,只是读取并立即将其写入同一目录,然后错误仍然存​​在。以下是演示该问题的一些示例代码:

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 打印出它向新的 .gz 文件写入了 169 字节。那么为什么当我 运行 stat -c %s test.tar.gz 我知道 test.tar.gz 的大小是 24?

这里有几件事:

  • 您正在声明一个 压缩的 文件以获取其大小,并从中读取一些 未压缩的 字节它。您没有提供 buffer_size 的任何定义或初始化,但您可能没有阅读整个文件,只是其中的一部分。

  • 您完全忽略了 gzread() 的 return 值,因此您不知道实际读取了多少字节。

  • 您正在读入 buffer 并写入 gz_buffer,这是未初始化的。

  • 然后您将压缩未初始化的内存并将其写入另一个文件。 gzwrite() returns 压缩的字节数,而不是压缩片段的长度(由于块、填充等依赖于未来写入的东西,它无法知道)。 169 个未压缩字节下降到 24 个压缩字节并不是不合理的。

  • 您没有进行任何错误检查;你的所有函数都应该进行检查以确保它们在对它们进行任何操作之前成功 return/set.