我目前正在尝试通过C中的套接字将.tar.gz文件从服务器传输到客户端,但是在使用gzopen + gzread从tar.gz读取并将其写入新文件时遇到了错误带有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也会打印其将169字节写入新的.gz文件。那为什么当我跑步时stat -c %s test.tar.gz
我知道test.tar.gz的大小是24吗?
这里有几件事:
您要声明一个[[compressed文件的大小,并从中读取一些uncompressed个字节。您没有提供buffer_size
的任何定义或初始化,但是您可能没有读取整个文件,只是其中的一部分。
gzread()
的返回值,因此您不知道实际读取了多少字节。buffer
并写入未初始化的gz_buffer
。gzwrite()
返回压缩的字节数,而不是压缩的片段的长度(由于诸如块,填充等之类的因素,它取决于将来的写入(如果有的话)而无法知道)。 169个未压缩字节降为24个压缩字节并非没有道理。