2012-10-25 50 views
4

我正在研究sc2replay解析工具。我建立它在MPQLIB http://code.google.com/p/mpqlib/Java 7文件通道調用映射方法後無法正常關閉

的頂部不幸的是,工具使用filechannels通過bZIP類文件的讀取, 並使用map(MapMode.READ_ONLY, hashtablePosition, hashTableSize);

調用該函數關閉文件通道不釋放文件中的過程後。 具體而言,我不能重命名/移動文件。在Java 7中發生

的問題,並能正常工作於Java 6

下面是一個簡單的代碼片段複製它:

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")); 

註釋掉fc.map將允許重新命名文件。

P.S.從這裏開始Should I close the FileChannel?

它聲明你不需要關閉filechannel和filestream,因爲關閉一個會關閉另一個。我也嘗試關閉或兩者都仍然沒有工作。

在Java 7上使用FileChannel.map讀取數據後重新命名文件是否有解決方法,因爲現在似乎每個人都有Java 7?

+0

是否關閉通道或流引發某種RuntimeException? – 0xCAFEBABE

+0

不會產生異常。我認爲這可能是Java 7本身的一個bug。我正在考慮將所有內容移植到.NET xD – tskaahyeah

回答

0

這是一個documented bug。該錯誤報告反駁了Java 1.4,他們認爲它是一個文檔錯誤。關閉文件通道不會關閉底層的流。

+1

@tskaahyeah這裏提到的錯誤報告是可疑的,並標記爲'無法重現'。關閉一個'FileChannel'關閉底層文件描述符:我在本週早些時候閱讀了源代碼。這裏的問題是關閉一個* mapped *文件不會釋放* mapping *。從上面 – EJP

+0

我試圖關閉filechannel和fileinputstream,也嘗試關閉fileinputstream只關閉filechannel只。一切都沒有工作。該代碼適用於java6,但不適用於java7 – tskaahyeah

2

好日子,

似乎FileChannel.map導致Java的,如果你使用FileChannel.map 7的問題,你可以不再關閉該文件。

一個快速的解決辦法是,而不是使用FileChannel.map(MapMode.READ_ONLY,位置,長度)

可以使用

ByteBuffer b = ByteBuffer.allocate(length); 
fc.read(b,position); 
b.rewind(); 
0

如果你使用的是Sun JRE,您可以通過欺騙投射到他們的實施並告訴它釋放自己。如果您不依賴於正在關閉的文件或者從未計劃使用其他JRE,我只會建議您這樣做。

在某些時候,我希望像這樣的東西能夠使它進入適當的公共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(); 
     } 
    } 
} 
相關問題