MappedByteBuffer - BufferOverflowException

MappedByteBuffer - BufferOverflowException

我正在使用 MappedByteBuffer 将记录写入文件。下面是我的代码。当我增加要写入的 numberOfRows 时,它抛出 BufferOverflowException。它适用于 1000 万个 numberOfRows。如果我将 numberOfRows 增加到 1 亿,它会抛出 BufferOverlowException!?

public static void writeOneFile() throws IOException{
     File file = File.createTempFile("outputfile", ".txt", new File("C:\Data\Output"));
     //f.delete();
     RandomAccessFile fileAccess = new RandomAccessFile(file, "rw");
     FileChannel fileChannel = fileAccess.getChannel();

     long bufferSize = (long) (Math.pow(10240, 2));//(long)(Math.pow(30720, 2));//(long) (Math.pow(1024, 2));//(long)Integer.MAX_VALUE;
     MappedByteBuffer mappedBuffer = fileChannel.map( FileChannel.MapMode.READ_WRITE, 0, bufferSize );

     long startPosMappedBuffer = 0;
     long million = 1000000; 
     long numberOfRows = million * 100; //million * 200 ;//1000;//million * 200 ; //200 million

     long startTime = System.currentTimeMillis();

     long counter = 1;
     //byte[] messageBytes = (counter+"").getBytes(Charset.forName("UTF-8"));
     //long bufferSize = (counter + "\n").getBytes(Charset.forName("UTF-8")).length * 1000;
     while(true)
     {         
         if( !mappedBuffer.hasRemaining() )
         {
             startPosMappedBuffer += mappedBuffer.position();
             mappedBuffer = fileChannel.map( FileChannel.MapMode.READ_WRITE, startPosMappedBuffer, bufferSize );
         }
         mappedBuffer.put( (counter + System.lineSeparator()).getBytes(Charset.forName("UTF-8")) ); //+ System.lineSeparator() //putLong( counter ); // ); 
         //mappedBuffer.rewind();

         counter++;
         if( counter > numberOfRows )
             break; 
     }
     fileAccess.close();
     long endTime = System.currentTimeMillis();
     long actualTimeTaken = endTime - startTime;
     System.out.println( String.format("No Of Rows %s , Time(sec) %s ", numberOfRows, actualTimeTaken / 1000f) ) ;  
 }

有什么问题的提示吗?

编辑 1:异常问题已解决并回答如下。

编辑 2:关于性能的最佳选择。

@EJP:这是在 BufferedOutputStream 周围使用 DataOutputStream 的代码。

static void writeFileDataBuffered() throws IOException{
        File file = File.createTempFile("dbf", ".txt", new File("C:\Output"));
        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream( file )));
        long counter = 1;
        long million = 1000000;
        long numberOfRows = million * 100;
        long startTime = System.currentTimeMillis();
        while(true){
            out.writeBytes( counter + System.lineSeparator() );
            counter++;
            if ( counter > numberOfRows )
                break;
        }
        out.close();
        long endTime = System.currentTimeMillis();
        System.out.println("Number of Rows: "+ numberOfRows + ", Time(sec): " + (endTime - startTime)/1000f);
    }

........ 谢谢

经过一些后台工作,我找到了根本原因。我声明的 bufferSize 小于我正在写的内容长度。

一亿条记录需要的字节数是:988888898,而带(long)(Math.pow(10240, 2))的bufferSize是:104857600。bufferSize短了884031298字节。如异常所示,这是导致问题的原因。

bufferSize也可以作为Integer.MAX_VALUE代替计算正在写入的内容大小。虽然这会增加文件大小,但根据我的试验 运行 结果,它不会对程序的性能产生任何影响。

.........

谢谢