尝试使用c++ gzlib和java GZIPOutputStream 读写gz压缩文件

来源:互联网 发布:linux上装eclipse 编辑:程序博客网 时间:2024/06/02 09:54

问题背景:

我需要生成一个大概1.5T的double型矩阵,硬盘受不了,IO时间消耗不起,于是尝试在输出前压缩。矩阵生成使用java,在矩阵上的计算使用cpp


于是分别尝试使用java 写gz压缩文件和使用c++读压缩文件


一下为简单的测试代码:

写:

 public boolean generateGzipFile(String ofname) throws IOException {                FileOutputStream fout = new FileOutputStream(ofname);                GZIPOutputStream gos = new GZIPOutputStream(fout);                for(int i = 0; i < numbers.size(); i++){                        String tstr = String.valueOf(numbers.get(i));                        tstr += "\n";                        gos.write(tstr.getBytes());                }                gos.finish();                gos.flush();                gos.close();                return true;        }

读:

#include <iostream>#include <stdlib.h>#include <string>#include <zlib.h>using namespace std;int main(int argc, char **argv){        if(argc != 2){                cerr << "example command: exe file.tar.gz" << endl;                return 0;        }        gzFile gzfp = gzopen(argv[1], "rb");        if(!gzfp)                return 0;        char buf[32];        while(gzgets(gzfp, buf, 31)){                cout << "str: " << buf << endl;                cout << "num: " << atof(buf) << endl;        }        return 0;}

需要注意的问题:

GZIPOutputStream只有一个write方法,只接受byte[],于是需要将double转换成byte[],有两条路:

1. double 直接转化成byte[]

 //byte dnum[] = new byte[8]; //ByteBuffer.wrap(dnum).putDouble(numbers.get(i)); //gos.write(dnum);


这种方法写入的文件,不能使用gunzip直接解压,解压会出乱码,因为文件存储double值是按照每个数字的char作为一个字节存储的,只能自己写解压程序,将byte[]转成double


2. double 转String再转byte[]


也就是我最终用的方法


最后,做了一些测试,gzip的压缩效果真心点赞

-rw-r--r-- 1  users  193843 Apr 20  2015 t10e4
-rw-r--r-- 1 users    5408 Apr 20  2015 t10e4.gz
-rw-r--r-- 1 users 1977688 Apr 20  2015 t10e5
-rw-r--r-- 1 users   80940 Apr 20  2015 t10e5.gz




0 0