java - Matlab 中的 GZIP 用于大文件

标签 java matlab gzip zlib matlab-java

我有一个解包字节数组的函数 Z使用 zlib 库打包(改编自 here )。

  • 打包后的数据大小为 4.11 GB,解包后的数据大小为 6.65 GB。我有 32GB 的内存,所以这远低于限制。
  • 我尝试将 java 堆大小增加到 15.96GB,但这没有帮助。
  • MATLAB_JAVA 环境变量指向 jre1.8.0_144。

  • 我得到了神秘的错误

    'MATLAB array exceeds an internal Java limit.' 
    

    在此代码的第 2 行:
    import com.mathworks.mlwidgets.io.InterruptibleStreamCopier
    a=java.io.ByteArrayInputStream(Z);
    b=java.util.zip.GZIPInputStream(a);
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier;
    c = java.io.ByteArrayOutputStream;
    isc.copyStream(b,c);
    M=typecast(c.toByteArray,'uint8');
    

    试图实现马克阿德勒的建议:
    Z=reshape(Z,[],8);
    import com.mathworks.mlwidgets.io.InterruptibleStreamCopier
    a=java.io.ByteArrayInputStream(Z(:,1));
    b=java.util.zip.GZIPInputStream(a);
    for ct = 2:8,b.read(Z(:,ct));end
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier;
    c = java.io.ByteArrayOutputStream;
    isc.copyStream(b,c);
    

    但是在这个isc.copystream我收到此错误:
    Java exception occurred:
    java.io.EOFException: Unexpected end of ZLIB input stream
    
        at java.util.zip.InflaterInputStream.fill(Unknown Source)
    
        at java.util.zip.InflaterInputStream.read(Unknown Source)
    
        at java.util.zip.GZIPInputStream.read(Unknown Source)
    
        at java.io.FilterInputStream.read(Unknown Source)
    
        at com.mathworks.mlwidgets.io.InterruptibleStreamCopier.copyStream(InterruptibleStreamCopier.java:72)
    
        at com.mathworks.mlwidgets.io.InterruptibleStreamCopier.copyStream(InterruptibleStreamCopier.java:51)
    

    直接从文件中读取
    我试图直接从文件中读取数据。
    streamCopier = com.mathworks.mlwidgets.io.InterruptibleStreamCopier.getInterruptibleStreamCopier;
    fileInStream = java.io.FileInputStream(java.io.File(filename));
    fileInStream.skip(datastart);
    gzipInStream = java.util.zip.GZIPInputStream( fileInStream );
    baos = java.io.ByteArrayOutputStream;
    streamCopier.copyStream(gzipInStream,baos);
    data = baos.toByteArray;
    baos.close;
    gzipInStream.close;
    fileInStream.close;
    

    适用于小文件,但对于大文件,我得到:
    Java exception occurred:
    java.lang.OutOfMemoryError
    

    在线streamCopier.copyStream(gzipInStream,baos);

    最佳答案

    瓶颈似乎是创建的每个 Java 对象的大小。这发生在 java.io.ByteArrayInputStream(Z)因为 MATLAB 数组不能在没有转换的情况下输入到 Java 中,而且在 copyStream 中也是如此。 ,其中数据实际上被复制到输出缓冲区/内存中。我有一个类似的想法,将对象分成允许大小的块( src ):

    function chunkDunzip(Z)
    %% Imports:
    import com.mathworks.mlwidgets.io.InterruptibleStreamCopier
    %% Definitions:
    MAX_CHUNK = 100*1024*1024; % 100 MB, just an example
    %% Split to chunks:
    nChunks = ceil(numel(Z)/MAX_CHUNK);
    chunkBounds = round(linspace(0, numel(Z), max(2,nChunks)) );
    
    V = java.util.Vector();
    for indC = 1:numel(chunkBounds)-1
      V.add(java.io.ByteArrayInputStream(Z(chunkBounds(indC)+1:chunkBounds(indC+1))));
    end
    
    S = java.io.SequenceInputStream(V.elements);  
    b = java.util.zip.InflaterInputStream(S);
    
    isc = InterruptibleStreamCopier.getInterruptibleStreamCopier;
    c = java.io.FileOutputStream(java.io.File('D:\outFile.bin'));
    isc.copyStream(b,c);
    c.close();
    
    end
    

    几个注意事项:
  • 我用了 FileOutputStream因为它没有遇到 Java 对象的内部限制(就我的测试而言)。
  • 仍然需要增加 Java 堆内存。
  • 我使用 deflate 来演示它,而不是 gzip。 gzip 的解决方案非常相似——如果这是一个问题,我会修改它。
  • 关于java - Matlab 中的 GZIP 用于大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733632/

    相关文章:

    java - 如何让一个jar文件一直运行

    java - 选项卡未调用 onCreateView

    java - MATLAB 代理无法在 180000 毫秒内创建

    NGINX 如何使 HTTP Basic Auth 页面 Gzip 启用

    python - 使用 Pyramid 压缩所有 HTTP 流量

    java - 此组件要求您指定有效的 TextAppearance 属性

    matlab - xy 散点图中每个条目的数据标签

    windows - 如何在 Matlab 编译器生成的 exe 的高 DPI 设置上禁用显示缩放

    javascript - 我可以假设我的 js 文件采用 gzip 压缩吗?

    java - ANTLR Ubuntu Java Makefile