我有一个解包字节数组的函数 Z
使用 zlib 库打包(改编自 here )。
我得到了神秘的错误
'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 - Matlab 中的 GZIP 用于大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46733632/