在Java中,从文本文件读取的最快方法是什么?

4

我目前使用:

BufferedReader input = new BufferedReader(new FileReader("filename"));

有更快的方法吗?

为什么你需要如此快的速度? - Simon Kuang
6个回答

11

虽然你所使用的方法可能不是绝对最快的,但它很简单。实际上,我不会使用那种形式 - 我会使用一些允许我指定字符集的东西,例如:

// Why is there no method to give this guaranteed charset
// without "risk" of exceptions? Grr.
Charset utf8 = Charset.forName("UTF-8");     
BufferedReader input = new BufferedReader(
                           new InputStreamReader(
                               new FileInputStream("filename"),
                               utf8));

你可能可以使用NIO使它运行更快,但在看到实际问题之前我不会这样做。如果你发现有问题,但同时又在对数据进行其他操作,请确保它们不是问题的原因:编写一个程序仅读取文件的文本内容。不要忘记在运行之间清除文件系统缓存所需的任何操作...


1
你到底怎么实例化InputStream? - Joshua Partogi
为什么不直接使用 new Scanner(new File(...)) - Simon Kuang
1
@SimonKuang:我不知道Scanner有多少缓冲区,而且个人非常讨厌Scanner API。如果你只需要读取文本行,那么使用它就是巨大的浪费——而我给出的每一行代码都是为了做一件事情。 - Jon Skeet
@JonSkeet 很抱歉有些失礼,但是你能否解释一下为什么这会过度吗?我个人认为它可以促进抽象性、与 _everything_(如果你选择)保持语法同质,并提供极大的便利。 - Simon Kuang
1
@SimonKuang:有一种更简单的类型可用,它可以满足所需的功能(使用缓冲区读取文本),而不需要其他责任(例如解析数字等)。当我需要一种仅用于读取文本的类型时,我会查看“Reader”类,而不是“Scanner”。此外,我可以将Reader传递给任何其他只对文本感兴趣的代码。例如,我可以从Reader加载Properties数据,但不能从Scanner中加载。我可以使用Reader解析XML,但不能使用Scanner - Jon Skeet
1
@SimonKuang: 我也强烈建议在构造从文件读取的Scanner时传入编码。不幸的是,Scanner不允许您传递Charset,只能传递名称...而InputStreamReader允许您指定Charset,所以我可以使用例如Java 7的StandardCharsets.UTF_8... - Jon Skeet

3
如果您想要快速处理数据,建议将字符数据保留为编码形式(不是UTF-16)。虽然磁盘I/O通常很慢(除非它被缓存),但解码和保留两倍的数据也可能成为问题。尽管最快的加载方式可能是通过java.nio.channels.FileChannel.map(MapMode.READ_ONLY, ...),但这种方法在释放内存方面存在严重问题。
请注意常见的警告提示。

1
请查看java.nio.channels.FileChannel。

0
File file = new File("querySourceFileName");
Scanner s = new Scanner(file);
while (s.hasNext()) {
    System.out.println(s.nextLine());
}

这是读取文件最明显和简单的方式。但你真的认为它在速度方面能与其他方式竞争吗? - f4lco

0

你有对其他选项进行性能测试吗?我想象在某些情况下,不使用 BufferedReader 可能会更快 - 比如处理非常小的文件。我建议你至少进行一些小型的性能测试,并找到适用于你典型使用场景的最快实现。


0

这取决于您想要阅读什么。完整的文件还是从特定位置开始,您需要能够搜索它,还是想一次性阅读完整的文本?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接