Sza*_*lcs 10 java wolfram-mathematica memory-mapped-files jlink
我是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?
}
}
Run Code Online (Sandbox Code Playgroud)
我想array()在缓冲区上使用该方法,所以我首先尝试将缓冲区内容加载到内存中load().但是,即使之后load(),isLoaded()返回false并buffer.array()抛出异常:java.lang.UnsupportedOperationException
at java.nio.ByteBuffer.array(ByteBuffer.java:940).
为什么不加载缓冲区以及如何调用该array()方法?
我的最终目标是获得一系列double的使用asDoubleBuffer().array().该方法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 *)
Run Code Online (Sandbox Code Playgroud)
根据Javadoc
“映射字节缓冲区的内容可以随时更改,例如,如果该程序或另一个程序更改了映射文件的相应区域的内容。无论是否发生此类更改以及何时发生,取决于操作系统,因此未指定。
全部或部分映射字节缓冲区可能随时变得不可访问,例如,如果映射文件被截断。尝试访问映射字节缓冲区的不可访问区域不会更改缓冲区的内容,并且会导致在访问时或稍后某个时间抛出未指定的异常。因此,强烈建议采取适当的预防措施,以避免该程序或同时运行的程序对映射文件进行操作,读取或写入文件内容除外。”
对我来说,这似乎有很多条件和不良行为。你特别需要这门课吗?
如果您只需要以最快的方式读取文件内容,请尝试:
FileChannel fChannel = new FileInputStream(f).getChannel();
byte[] barray = new byte[(int) f.length()];
ByteBuffer bb = ByteBuffer.wrap(barray);
bb.order(ByteOrder.LITTLE_ENDIAN);
fChannel.read(bb);
Run Code Online (Sandbox Code Playgroud)
它的工作速度几乎等于磁盘系统测试速度。
对于 double,您可以使用 DoubleBuffer(如果 f.length()/4 大小,则使用 double[] 数组)或仅调用 ByteBuffer 的 getDouble(int) 方法。
| 归档时间: |
|
| 查看次数: |
5574 次 |
| 最近记录: |