2015-02-10 128 views
0

我正在學習java nio,我正在使用MappedByteBuffer和ExecutorService異步複製文件。我的問題是方法MappedByteBuffer.put()拋出java.nio.BufferOverflowException。但在我的調試中,我沒有複製到我的目標文件上的位置。這是代碼的一部分,我用它來創建該文件的新副本:MappedByteBuffer拋出一個java.nio.BufferOverflowException

for (Future<?> f : futures) { 
       Message message = (Message) f.get(); 
       try (FileChannel fileChannel = (FileChannel) Files 
         .newByteChannel(pathWrite, EnumSet.of(
           StandardOpenOption.READ, 
           StandardOpenOption.WRITE, 
           StandardOpenOption.TRUNCATE_EXISTING))) { 
        MappedByteBuffer mbb = fileChannel.map(
          FileChannel.MapMode.READ_WRITE, message.getCod(), 
          message.getValue()); 

        if (mbb != null) { 
         System.out.println("start: " + message.getCod() 
           + " - end: " + message.getValue()); 
         ByteBuffer encode = Charset.forName(charEncoding) 
           .encode(message.getCharBuffer()); 
         mbb.put(encode); // here 
        } 
       } catch (IOException ioe) { 
        ioe.printStackTrace(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 

和例外是:

java.nio.BufferOverflowException 
    at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:363) 
    at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:342) 
    at memo.MultiThreadingMappedByteBufferExample.multiThreadedWayWithExecutorService(MultiThreadingMappedByteBufferExample.java:139) 

回答

1

你截斷文件長度爲零,一些映射它的未知部分根據message.getCod()message.getValue()提供的偏移量和長度值,因文件長度爲零而不存在,然後試圖將提供了該消息的charBuffer放入文件中,該文件仍爲零長度,在由message.getCod()定義的不存在的偏移處,所以你得到一個BufferOverflowException

我建議你不要截斷文件開始,但它不明白爲什麼這應該工作。我建議你使用RandomAccessFile。簡單。你不應該在單個應用程序中使用大量的內存映射文件,而僅僅爲了這個小小的工作而使用它是不合適的。

+0

正如我正在學習java nio我想使用它的方式來提高使用併發和異步作業的大型程序的性能。這只是第一次嘗試幫助我進行大嘗試。如果你對MappedByteBuffer有一些例子,它會對我非常有幫助。不管怎麼說,還是要謝謝你。 – 2015-02-10 00:56:25

+1

它不會改善性能。它會使情況變得更糟。 [Javadoc](https://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#map(java.nio.channels.FileChannel.MapMode,%20long,%20long ))這樣說:「對於大多數操作系統來說,將文件映射到內存中比使用通常的讀寫方法讀取或寫入幾十千字節的數據要昂貴。從性能的角度來看,它通常只值得相對映射大文件進入內存「。如果你只是在學習Java,那麼你應該首先以簡單的方式做事。 – EJP 2015-02-10 01:00:05

相關問題