我非常新手Java,并尝试使用Mathematica的Java接口使用内存映射访问文件(希望能提高性能)。
我有的Mathematica代码(我相信)等同于以下Java代码(基于此链接):
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
public class MainClass {
private static final int LENGTH = 8*100;
public static void main(String[] args) throws Exception {
MappedByteBuffer buffer = new FileInputStream("test.bin").getChannel().map(FileChannel.MapMode.READ_ONLY, 0, LENGTH);
buffer.load();
buffer.isLoaded(); // returns false, why?
}
}
我想在缓冲区上使用array()
方法,因此我试图先使用load()
将缓冲区内容加载到内存中。但是,即使load()
之后,isLoaded()
仍返回false
,buffer.array()
会抛出异常:java.lang.UnsupportedOperationException at java.nio.ByteBuffer.array(ByteBuffer.java:940)
。
为什么缓冲区没有加载,我该如何调用array()
方法?
我的最终目标是使用asDoubleBuffer().array()
获取一个double
数组。虽然方法getDouble()
可以正常工作,但我希望一次完成以获得良好的性能。我做错了什么?
由于我是从Mathematica进行操作的,因此我也会发布实际使用的Mathematica代码(相当于Java中的上述代码):
Needs["JLink`"]
LoadJavaClass["java.nio.channels.FileChannel$MapMode"]
buffer = JavaNew["java.io.FileInputStream", "test.bin"]@getChannel[]@map[FileChannel$MapMode`READUONLY, 0, 8*100]
buffer@load[]
buffer@isLoaded[] (* returns False *)
load
仅尽最大努力加载数据,实际上可能仅将数据加载到物理内存中,但随即被交换出去。 - Tom Hawtin - tacklinearray
仅适用于由数组支持的缓冲区(通常来自*Buffer.wrap
)。 - Tom Hawtin - tackline