Java.io : Performance Tuning

标签 java file-io io nio filereader

我有一个大约 4MB 的文件,该文件是一个仅包含普通键盘字符的 ascii 文件。我尝试了 java.io 包中的许多类来将文件内容读取为字符串。逐个字符地读取它们(使用 FileReader 和 BufferedReader)需要 大约 40 秒,使用 java.nio 包(FileChannel 和 ByteBuffer)读取内容大约需要 25 秒。这是从我的知识多一点 多少时间。有人知道有什么方法可以减少这个时间消耗吗 大约 10 秒?甚至像使用 C 创建文件阅读器和从 java 调用这样的解决方案也可以。我使用下面的代码片段在 22 秒内读取了 4 MB 的文件-

public static String getContents(File file) {
    try {
        if (!file.exists() && !file.isFile()) {
            return null;
        }
        FileInputStream in = new FileInputStream(file);
        FileChannel ch = in.getChannel();
        ByteBuffer buf = ByteBuffer.allocateDirect(512);            
        Charset cs = Charset.forName("ASCII");          
        StringBuilder sb = new StringBuilder();
        int rd;
        while ((rd = ch.read(buf)) != -1) {
            buf.rewind();
            CharBuffer chbuf = cs.decode(buf);
            for (int i = 0; i < chbuf.length(); i++) {
                sb.append(chbuf.get());
            }
            buf.clear();
        }
        String contents = sb.toString();
        System.out.println("File Contents:\n"+contents);
        return contents;
    } catch (Exception exception) {
        System.out.println("Error:\n" + exception.getMessage());
        return null;
    }
}

最佳答案

我无法想象您的硬件是什么,但处理一个 4 MB 的文件应该不到 0.1 秒。

一次读取所有文件的快速方法是将其读入字节[]

public static String readFileAsString(File file) {
    try {
        DataInputStream in = new DataInputStream(FileInputStream(file));
        byte[] bytes = new byte[(int) file.length()];
        in.readFully(bytes);
        in.close();
        return new String(bytes, 0); // ASCII text only.

    } catch (FileNotFoundException e) {
        return null;
    } catch (IOException e) {
        System.out.println("Error:\n" + e.getMessage());
        return null;
    }
}

public static void main(String... args) throws IOException {
    File tmp = File.createTempFile("deleteme", "txt");
    tmp.deleteOnExit();

    byte[] bytes = new byte[4 * 1024 * 1024];
    Arrays.fill(bytes, (byte) 'a');
    FileOutputStream fos = new FileOutputStream(tmp);
    fos.write(bytes);
    fos.close();

    long start = System.nanoTime();
    String s = readFileAsString(tmp);
    long time = System.nanoTime() - start;
    System.out.printf("Took %.3f seconds to read a file with %,d bytes%n",
            time / 1e9, s.length());
}

打印

Took 0.026 seconds to read a file with 4,194,304 bytes

如果你想更快地读取文件,我建议使用内存映射文件,因为它只需要不到 10 毫秒,但在这种情况下已经过时了。

关于Java.io : Performance Tuning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10087534/

相关文章:

java - 添加对解析器的引用以获取分离的 XAdES 签名

java - java中的package语句有什么理由应该放在开头吗?

java - 空对象引用上的 ListView.setAdapter(android.widget.ListAdapter)'

perl - 如何用Perl将指定格式的数据写入二进制文件?

html - 使用 VBA 将本地 HTML 文件读入字符串

java - Spring 文件上传。要求文件存在

javascript - 在nodejs中使用wait.for暂停非阻塞文件读取

file-io - Elixir:写入文件并创建父目录(如果不存在)-一行

string - Haskell 读取文件 : Couldn't match expected type ‘[String]’ with actual type ‘IO String’

Java InputStream 读取方法为 NFS 安装位置中的文件返回 ASCII 'NUL' 字符