我正在研究的一个优化项目现在大量使用EPANet。我们在EPANet中反复调用两种模拟方法,以了解水如何流经配水网络。
HydraulicSim是我们使用的课程之一。请参阅重载的simulate
方法:
public void simulate(File hyd) throws ENException {
...
}
public void simulate(OutputStream out) throws ENException, IOException {
...
}
public void simulate(DataOutput out) throws ENException, IOException {
...
}
我们使用的另一个类是QualitySim。在这里,我们还使用了重载的simulate
方法:
public void simulate(File hydFile, File qualFile) throws IOException, ENException {
...
}
void simulate(File hydFile, OutputStream out) throws IOException, ENException {
...
}
以下是我们目前正在做的事情:
File
个对象,hydFile
和qualFile
。HydraulicSim.simulate
上致电hydFile
。QualitySim.simulate
和hydFile
上致电qualFile
。问题是我们必须经常做很多次。对于一个大问题,我们可以做到数十万甚至数百万次。您可以想象减速反复创建/写入/删除这些文件的原因。
所以我的问题是:我是否可以创建这些文件,使它们只驻留在内存中,永远不会触及磁盘?每个文件都很小(我说的是几百个字节),所以把它们扔进内存不会有问题;我只需要弄清楚如何。除了MappedByteBuffer之外,我在周围搜索并没有找到太多,但我不确定如何,或者甚至可能从该类创建File
。
欢迎任何建议!
答案 0 :(得分:6)
最直接的解决方案是在此处安装ramdisk和store文件。然后你不需要触摸你的代码,文件访问将是闪电般快速:-)
<强>的Linux 强>
# mkfs -q /dev/ram1 8192
# mkdir -p /ramcache
# mount /dev/ram1 /ramcache
<强>的MacOS 强>
答案 1 :(得分:3)
您可以使用 Memory mapped file 。 Java以FileChannel
类提供API,例如
channel.map(FileChannel.MapMode.READ_WRITE, start, PAGE_SIZE)
public abstract MappedByteBuffer map(FileChannel.MapMode mode,
long position,
long size)
throws IOException
Java仅提供32位指针来操作MappedByteBuffer
,但您可以使用切片来映射超过2GB的文件,例如。
private void memoryMapFile(File file) throws FileNotFoundException, IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
FileChannel channel = randomAccessFile.getChannel();
List<MappedByteBuffer> buffers = new ArrayList<MappedByteBuffer>();
long size = channel.size();
long start = 0;
int index = 0;
for (index = 0; start + PAGE_SIZE <= size; index++) {
buffers.add(index, channel.map(FileChannel.MapMode.READ_WRITE, start, PAGE_SIZE));
start = (index+1)*PAGE_SIZE;
}
if(start+PAGE_SIZE > size){
buffers.add(index, channel.map(FileChannel.MapMode.READ_WRITE, start, PAGE_SIZE));
}
}
答案 2 :(得分:2)
它可能有点过分,但Java 7提供了一种创建自定义文件系统的方法:
http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html
您可以使用它来创建自己的内存文件系统,该系统由Map或byte []支持。但是,似乎FileSystem使用新的Path
对象,而不是File
(尽管有转换为/从文件转换的方法)
尽管你想要做的事情可能会有点过分。
答案 3 :(得分:2)
向EPANet团队提交问题可能是值得的。模拟方法都只使用File对象来获取输入和输出流。如果他们提供了QualitySim.simulate
方法,将流作为params(它们用于输出流而不是输入流),则可以绕过FS。或者只是分叉并自己动手。