是否可以在Java中创建内存中的File对象?

时间:2014-03-10 17:46:05

标签: java

我正在研究的一个优化项目现在大量使用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 {
    ...
}

以下是我们目前正在做的事情:

  1. 创建两个File个对象,hydFilequalFile
  2. HydraulicSim.simulate上致电hydFile
  3. QualitySim.simulatehydFile上致电qualFile
  4. 删除文件。
  5. 问题是我们必须经常做很多次。对于一个大问题,我们可以做到数十万甚至数百万次。您可以想象减速反复创建/写入/删除这些文件的原因。

    所以我的问题是:我是否可以创建这些文件,使它们只驻留在内存中,永远不会触及磁盘?每个文件都很小(我说的是几百个字节),所以把它们扔进内存不会有问题;我只需要弄清楚如何。除了MappedByteBuffer之外,我在周围搜索并没有找到太多,但我不确定如何,或者甚至可能从该类创建File

    欢迎任何建议!

4 个答案:

答案 0 :(得分:6)

最直接的解决方案是在此处安装ramdisk和store文件。然后你不需要触摸你的代码,文件访问将是闪电般快速:-)

<强>的Linux

# mkfs -q /dev/ram1 8192
# mkdir -p /ramcache
# mount /dev/ram1 /ramcache

<强>的MacOS

  1. http://osxdaily.com/2007/03/23/create-a-ram-disk-in-mac-os-x/
  2. <强>窗

    1. http://support.microsoft.com/kb/257405
    2. http://www.softperfect.com/products/ramdisk/

答案 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。或者只是分叉并自己动手。