我正在开发一个包含大约400个输入文件和大约40个输出文件的程序。 它很简单:它读取每个输入文件,并生成一个新文件但更大(基于算法)。
我正在使用BufferedReader中的read()方法:
String encoding ="ISO-8859-1";
FileInputStream fis = new FileInputStream(nextFile);
BufferedReader reader = new BufferedReader(new InputStreamReader(fis, encoding));
char[] buffer = new char[8192] ;
要读取我正在使用的输入文件:
private String getNextBlock() throws IOException{
boolean isNewFile = false;
int n = reader.read(buffer, 0, buffer.length);
if(n == -1) {
return null;
} else {
return new String(buffer,0,n);
}
}
对于每个块,我正在进行一些检查(比如查看块内部的一些字符串),然后我将其写入文件中:
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("fileName"), encoding));
writer.write(textToWrite);
问题在于它需要大约12分钟。 我想要更快地找到别的东西。 任何人都对某些事情有了更好的了解吗?
感谢。
答案 0 :(得分:20)
你应该可以在这里找到答案:
http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly
要获得最佳的Java读取性能,需要记住四件事:
通过一次读取数组来最小化I / O操作,而不是一次读取一个字节。一个8K字节的阵列是一个很好的大小。
通过一次获取数据数组来最小化方法调用,而不是一次获取一个字节。使用数组索引来获取数组中的字节数。
如果您不需要线程安全,请最小化线程同步锁。对线程安全类进行较少的方法调用,或者使用非线程安全的类,如FileChannel和MappedByteBuffer。
最大限度地减少JVM / OS,内部缓冲区和应用程序阵列之间的数据复制。将FileChannel与内存映射一起使用,或使用直接或包装的数组ByteBuffer。
答案 1 :(得分:4)
由于您没有提供太多详细信息,我可能会提示您尝试使用内存映射文件:
FileInputStream f = new FileInputStream(fileName);
FileChannel ch = f.getChannel( );
MappedByteBuffer mbb = ch.map( ch.MapMode.READ_ONLY, 0L, ch.size( ) );
while ( mbb.hasRemaining( ) ) {
// Access the data using the mbb
}
如果您想详细说明您的文件包含哪种数据,则可以对其进行优化。
修改强>
//使用mbb访问日期在哪里,您对文本进行冷解码:
String charsetName = "UTF-16"; // choose the apropriate charset.
CharBuffer cb = Charsert.forName(charsetName).decode(mbb);
String text = cb.toString();
答案 2 :(得分:1)
映射字节缓冲区是最快的方法:
FileInputStream f = new FileInputStream( name );
FileChannel ch = f.getChannel( );
MappedByteBuffer mb = ch.map( ch.MapMode.READ_ONLY,
0L, ch.size( ) );
byte[] barray = new byte[SIZE];
long checkSum = 0L;
int nGet;
while( mb.hasRemaining( ) )
{
nGet = Math.min( mb.remaining( ), SIZE );
mb.get( barray, 0, nGet );
for ( int i=0; i<nGet; i++ )
checkSum += barray[i];
}