如何最有效地将文件(从Java读取)传递给本机方法?

我有约. 30000个文件(每个1MB)我想放入一个本机方法,它只需要一个字节数组,并且它的大小作为参数.

我查看了一些示例和基准(如http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly),但所有这些都做了一些其他奇特的事情.

基本上我不关心文件的内容,我不想访问该文件或字节数组中的内容或使用它做任何其他事情.我只想将一个文件放入一个本机方法,该方法尽可能快地接受一个字节数组.

目前我正在使用RandomAccessFile,但速度非常慢(10MB / s).

有没有像

byte[] readTheWholeFile(File file){ ... }

我可以投入

native void fancyCMethod(readTheWholeFile(myFile), myFile.length())

你会建议什么?

最佳答案 使用常规数组可能效率低,因为VM可能在将数组传递给本机代码时复制数组,并且还可能在I / O期间使用中间存储器.

对于最快的IO,使用ByteBuffer.allocateDirect分配字节缓冲区.底层数组是“特殊的”,因为它不是常规JVM堆的一部分.本机代码和I / O可以直接访问阵列.

要将数据读入缓冲区使用,

ByteBuffer byteBuffer = ByteBuffer.allocateDirect(randomAccessFile.length());
RandomAccessFile.getChannel().read(byteBuffer, 0);

要使后备数组传递给JNI使用

byte[] byteArray = byteBuffer.array();

然后,您可以将此数组和文件长度传递给JNI.

直接缓冲区实际上很难创建,因为所有文件都是1MB(或左右),您应该能够在多个文件上重用相同的缓冲区.

希望这可以帮助!

点赞