Java 7 filechannel not closing properly after calling map method

I am working on a sc2replay syntax analysis tool. I create it on top of MPQLIB http://code.google.com/p/mpqlib/

Unfortunately, the tool uses file channels to read bzip files, and uses map(MapMode.READ_ONLY, hashtablePosition, hashTableSize);

After calling this function, closing the file channel does not free the file in the process. To be specific, I cannot rename / move the file.

The problem occurs in Java 7, and it works fine in Java 6.

Here is a simple snippet of code to replicate it:

  FileInputStream f = new FileInputStream("test.SC2Replay"); FileChannel fc = f.getChannel(); fc.map(MapMode.READ_ONLY, 0,1); fc.close(); new File("test.SC2Replay").renameTo(new File("test1.SC2Replay")); 

Commenting fc.map will allow you to rename the file.

PS from here Should I close the FileChannel?

It states that you do not need to close both the file and the file, because the close will be closed. I also tried closing either or both, and still did not work.

Is there a workaround when renaming a file after reading data using FileChannel.map in Java 7, because each of them seems to have Java 7 currently?

+4
source share
3 answers

Good afternoon,

it seems that FileChannel.map is causing a problem with java 7. If you use FileChannel.map, you can no longer close the file.

for fast work is used instead of FileChannel.map (MapMode.READ_ONLY, position, length)

you can use

 ByteBuffer b = ByteBuffer.allocate(length); fc.read(b,position); b.rewind(); 
+2
source

This is a documented error . The error report relates to Java 1.4, and they consider this a documentation error. Closing a file channel does not close the underlying stream.

0
source

If you use the Sun JRE, you can cheat by dropping their implementation and reporting it to free yourself. I would recommend doing this if you do not rely on a file to close or you never plan on using another JRE.

At some point, I hope that something like this will turn it into a proper public API.

 try (FileInputStream stream = new FileInputStream("test.SC2Replay"); FileChannel channel = stream.getChannel()) { MappedByteBuffer mappedBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, 1); try { // do stuff with it } finally { if (mappedBuffer instanceof DirectBuffer) { ((DirectBuffer) mappedBuffer).cleaner().clean(); } } } 
0
source

Source: https://habr.com/ru/post/1442002/


All Articles