java-如何使用Zstd-jni和字节缓冲区解压缩大文件
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-如何使用Zstd-jni和字节缓冲区解压缩大文件,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3161字,纯文字阅读大概需要5分钟。
内容图文
我尝试使用ByteBuffers和Channels并行下载大量40 MB文件时解压缩.与使用Streams相比,使用Channels可以获得更高的吞吐量,我们需要这是一个非常高的吞吐量的系统,因为我们每天需要处理40 TB的文件,而这一部分目前是瓶颈.文件使用zstd-jni压缩.Zstd-jni具有用于解压缩字节缓冲区的api,但是使用它们时出现错误.如何使用zstd-jni一次解压缩字节缓冲区?
我在他们的测试中找到了这些示例,但是除非丢失了某些内容,否则使用ByteBuffers的示例似乎假定整个输入文件都适合一个ByteBuffer:
https://github.com/luben/zstd-jni/blob/master/src/test/scala/Zstd.scala
以下是我用于压缩和解压缩文件的代码.压缩代码效果很好,但是解压缩代码失败,错误为-70.
public static long compressFile(String inFile, String outFolder, ByteBuffer inBuffer, ByteBuffer compressedBuffer, int compressionLevel) throws IOException {
File file = new File(inFile);
File outFile = new File(outFolder, file.getName() + ".zs");
long numBytes = 0l;
try (RandomAccessFile inRaFile = new RandomAccessFile(file, "r");
RandomAccessFile outRaFile = new RandomAccessFile(outFile, "rw");
FileChannel inChannel = inRaFile.getChannel();
FileChannel outChannel = outRaFile.getChannel()) {
inBuffer.clear();
while(inChannel.read(inBuffer) > 0) {
inBuffer.flip();
compressedBuffer.clear();
long compressedSize = Zstd.compressDirectByteBuffer(compressedBuffer, 0, compressedBuffer.capacity(), inBuffer, 0, inBuffer.limit(), compressionLevel);
numBytes+=compressedSize;
compressedBuffer.position((int)compressedSize);
compressedBuffer.flip();
outChannel.write(compressedBuffer);
inBuffer.clear();
}
}
return numBytes;
}
public static long decompressFile(String originalFilePath, String inFolder, ByteBuffer inBuffer, ByteBuffer decompressedBuffer) throws IOException {
File outFile = new File(originalFilePath);
File inFile = new File(inFolder, outFile.getName() + ".zs");
outFile = new File(inFolder, outFile.getName());
long numBytes = 0l;
try (RandomAccessFile inRaFile = new RandomAccessFile(inFile, "r");
RandomAccessFile outRaFile = new RandomAccessFile(outFile, "rw");
FileChannel inChannel = inRaFile.getChannel();
FileChannel outChannel = outRaFile.getChannel()) {
inBuffer.clear();
while(inChannel.read(inBuffer) > 0) {
inBuffer.flip();
decompressedBuffer.clear();
long compressedSize = Zstd.decompressDirectByteBuffer(decompressedBuffer, 0, decompressedBuffer.capacity(), inBuffer, 0, inBuffer.limit());
System.out.println(Zstd.isError(compressedSize) + " " + compressedSize);
numBytes+=compressedSize;
decompressedBuffer.position((int)compressedSize);
decompressedBuffer.flip();
outChannel.write(decompressedBuffer);
inBuffer.clear();
}
}
return numBytes;
}
解决方法:
是的,您在示例中使用的静态方法假定整个压缩文件都适合一个ByteBuffer.据我了解您的要求,您需要使用ByteBuffers进行流式解压缩. ZstdDirectBufferDecompressingStream已经提供了以下功能:
这是一个示例(从测试中)如何使用它:
https://github.com/luben/zstd-jni/blob/master/src/test/scala/Zstd.scala#L261-L302
但您还必须对其进行子类化并覆盖“重新填充”方法.
编辑:这是我刚刚添加的新测试,它的结构与您的问题完全相同-在通道之间移动数据:
https://github.com/luben/zstd-jni/blob/master/src/test/scala/Zstd.scala#L540-L586
内容总结
以上是互联网集市为您收集整理的java-如何使用Zstd-jni和字节缓冲区解压缩大文件全部内容,希望文章能够帮你解决java-如何使用Zstd-jni和字节缓冲区解压缩大文件所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。