Is it possible to create a memory object in memory in Java?

One of the optimization projects I'm currently working on is using EPANet extensively . We repeatedly turn to the two modeling methods in EPANet to understand how water flows through a water distribution network.

HydraulicSim is one of the classes we use. See Overloaded simulate methods:

 public void simulate(File hyd) throws ENException { ... } public void simulate(OutputStream out) throws ENException, IOException { ... } public void simulate(DataOutput out) throws ENException, IOException { ... } 

The other class we use is QualitySim . Here we also use the overloaded simulate methods:

 public void simulate(File hydFile, File qualFile) throws IOException, ENException { ... } void simulate(File hydFile, OutputStream out) throws IOException, ENException { ... } 

Here is what we are doing now:

  • Create two File objects, hydFile and qualFile .
  • Call HydraulicSim.simulate on hydFile .
  • Call QualitySim.simulate on hydFile and qualFile .
  • Delete files.

The problem is that we have to do this many times. For a big problem, we can do this hundreds of thousands or even millions of times. You can imagine that the slowdown is repeated when creating / writing / deleting these files.

So my question is this: is it possible to create these files so that they are only in memory and never touch the disk? Each file is very small (I say a few hundred bytes), so throwing them into memory will not be a problem; I just need to figure out how to do this. I searched around and didn't really find much except for MappedByteBuffer , but I'm not sure how and if possible to create a File from this class.

Any advice is appreciated!

+8
java
source share
4 answers

It might be worth sending a question to the EPANet team. Simulation methods simply use File objects to receive input and output streams. If they provided the QualitySim.simulate method, which passed the streams as parameters (what they do for the output stream, but not for the input stream), you can bypass FS. Or just branch it and make it yourself.

+2
source share

The easiest solution is to install ramdisk and save the file here. Then you do not need to touch the code, and access to the files will be lightning fast :-)

Linux

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

MacOS

Window

+6
source share

You can use a memory mapped file . Java provides an API in the FileChannel class, for example.

 channel.map(FileChannel.MapMode.READ_WRITE, start, PAGE_SIZE) public abstract MappedByteBuffer map(FileChannel.MapMode mode, long position, long size) throws IOException 

Java only provides a 32-bit pointer to control a MappedByteBuffer , but you can use a slice to display more than 2 GB of a file, for example.

 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)); } } 
+3
source share

This may be excessive, but Java 7 provides a way to create custom file systems:

http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html

You can use this to create your own in-memory file system, which is supported by the card or byte [] s. However, it looks like the FileSystem is using a new Path object, not a File (although there are methods for converting to / from a file)

It may be redundant for what you are trying to do, though.

+2
source share

All Articles