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代替计算正在写入的内容大小。虽然这会增加文件大小,但根据我的试验 运行 结果,它不会对程序的性能产生任何影响。
.........
谢谢
我正在使用 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代替计算正在写入的内容大小。虽然这会增加文件大小,但根据我的试验 运行 结果,它不会对程序的性能产生任何影响。
.........
谢谢