更快的方式来读取文件

CC.*_*CC. 9 java performance file-io

我正在开发一个包含大约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] ;
Run Code Online (Sandbox Code Playgroud)

要读取我正在使用的输入文件:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

对于每个块,我正在进行一些检查(比如在块中查找一些字符串),然后我将其写入文件:

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
        new FileOutputStream("fileName"), encoding));

writer.write(textToWrite);
Run Code Online (Sandbox Code Playgroud)

问题是大约需要12分钟.我想要更快地找到别的东西.谁有更好的想法?

谢谢.

net*_*ain 20

你应该能够在这里找到答案:

http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly

要获得最佳的Java读取性能,需要记住以下四点:

  • 通过一次读取一个数组来最小化I/O操作,而不是一次读取一个字节.一个8K字节的阵列是一个很好的大小.

  • 通过一次获取数据数组来最小化方法调用,而不是一次获取一个字节.使用数组索引来获取数组中的字节数.

  • 如果不需要线程安全,请最小化线程同步锁.对线程安全类进行较少的方法调用,或者使用非线程安全的类,如FileChannel和MappedByteBuffer.

  • 最大限度地减少JVM/OS,内部缓冲区和应用程序阵列之间的数据复制.将FileChannel与内存映射一起使用,或使用直接或包装的数组ByteBuffer.

  • 仅限链接的答案并不理想.你能否至少总结一下这篇文章的发现?(谢谢!) (4认同)

Pih*_*Pih 5

由于您没有提供太多细节,我可以建议您尝试使用内存映射文件:

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
}
Run Code Online (Sandbox Code Playgroud)

如果您提供有关文件具有哪种数据的更多详细信息,则可以对其进行优化。

编辑

// 使用 mbb 访问日期在哪里,您冷解码您的文本:

String charsetName = "UTF-16"; // choose the apropriate charset.
CharBuffer cb =  Charsert.forName(charsetName).decode(mbb);
String text = cb.toString();
Run Code Online (Sandbox Code Playgroud)