2015-02-10 133 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

相关问题