我一直在尝试使用C中的 gzip-based 文件IO函数打开并读取 gzip 压缩文件。我和我一起使用的压缩文件非常大大小为12 GB。未压缩的文件 ~260 GB ,因此我不准备使用gunzip解压缩文件并从那里继续。
我特意使用以下代码来读取和写入我们可用的缓冲区 -
let g:codi#interpreters = {
\ 'javascript': {
\ 'rightalign': 0,
\ },
\ }
代码根据您最初指定的缓冲区准确地从zlib文件读取和写入。缓冲区大小固定为某个值(在上述情况下为 0x4000 )。
现在的问题是我无法将此缓冲区的大小增加到某个值以上(我可以使用3276008作为缓冲区大小,但不能使用32760008 )。要读取12 GB的压缩值,需要使用非常大的缓冲区。正如我的编辑中所指出的,这看起来像某种#define windowBits 15
#define ENABLE_ZLIB_GZIP 32
#define CHUNK 0x4000
#define CALL_ZLIB(x) { \
int status; \
status = x; \
if (status < 0) \
{ \
fprintf(stderr, "%s:%d: %s returned a bad status of %d.\n", __FILE__, __LINE__, #x, status); \
exit(EXIT_FAILURE);\
} \
} \
int main ()
{
const char * file_name = "test.gz";
FILE * file;
z_stream strm = {0};
unsigned char in[CHUNK];
unsigned char out[CHUNK];
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.next_in = in;
strm.avail_in = 0;
CALL_ZLIB (inflateInit2 (& strm, windowBits | ENABLE_ZLIB_GZIP));
/* Open the file. */
file = fopen (file_name, "rb");
while (1) {
int bytes_read;
bytes_read = fread (in, sizeof (char), sizeof (in), file);
strm.avail_in = bytes_read;
do {
unsigned have;
strm.avail_out = CHUNK;
strm.next_out = out;
CALL_ZLIB (inflate (& strm, Z_NO_FLUSH));
have = CHUNK - strm.avail_out;
fwrite (out, sizeof (unsigned char), have, stdout);
}
while (strm.avail_out == 0);
if (feof (file)) {
inflateEnd (& strm);
break;
}
}
return 0;
}
而不是DATA_ERROR
错误...所以它毕竟不是缓冲区错误!
有什么方法可以使用上面的BUFFER
函数记录整个12 GB压缩文件?
编辑#1
函数zlib
返回的错误代码由inflate
函数封装,我很遗憾未包含该函数。因此,当我使用0x4000的缓冲区大小运行时,我得到以下错误代码。我已将CALL_ZLIB函数添加到代码中供您参考。
错误消息:
CALL_ZLIB
。这显然看起来像** DATA_ERROR。
编辑#2
我尝试将一个负值windowBits 添加到InflateInit2(),但这并没有解决我的任何问题。 inflate()函数最初正确读取我的文件 - 以我想要的方式显示我的所有数据..
parser.c:96: inflate(&strm, Z_NO_FLUSH) returned a bad status of -3
但过了一段时间后,显示的输出变得乱码,我再也看不懂了..
0x55b0 [0x40]: event: 3
.
. ... raw event: size 64 bytes
. 0000: 03 00 00 00 00 00 40 00 18 03 00 00 18 03 00 00 ......@.........
. 0010: 4d 6f 64 65 6d 4d 61 6e 61 67 65 72 00 00 00 00 ModemManager....
. 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
. 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0 0 0x55b0 [0x40]: PERF_RECORD_COMM: ModemManager:792/792
0x55f0 [0x40]: event: 7
.
. ... raw event: size 64 bytes
. 0000: 07 00 00 00 00 00 40 00 19 03 00 00 01 00 00 00 ......@.........
. 0010: 19 03 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................
. 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
. 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0 0 0x55f0 [0x40]: PERF_RECORD_FORK(793:793):(1:1)
0x5630 [0x40]: event: 3
.
这最终终止于我在编辑#1
中描述的错误消息答案 0 :(得分:0)
我已经解决了这个问题。
基本问题是我没有在循环内的代码中初始化z_stream的strm.next_in
成员。因此,在进行1次迭代后,缓冲区被破坏,我得到了上述错误。
我将代码修改为 -
strm.next_in = in;
strm.avail_in = 0;
CALL_ZLIB(inflateInit2 (&strm, windowBits | ENABLE_ZLIB_GZIP));
file = fopen(filename, "rb");
while(1)
{
int bytes_read;
strm.next_in = in; // added this line
bytes_read = fread(in, sizeof(char), sizeof(in), file);
strm.avail_in = bytes_read;
do
{
unsigned have;
strm.avail_out = CHUNK;
strm.next_out = out;