比 Scanner 或 BufferedReader 从 STDIN 读取多行数据更快的方式?
Posted
技术标签:
【中文标题】比 Scanner 或 BufferedReader 从 STDIN 读取多行数据更快的方式?【英文标题】:Faster way than Scanner or BufferedReader reading multiline data from STDIN? 【发布时间】:2011-07-07 12:50:56 【问题描述】:注意:我目前正在使用 java 进行编码。我希望将输入数据读入一个字符串,一次一行(或更多行),我希望总行数很多。
现在我已经实现了
scanner in = new Scanner(System.in)
while (in.hasNextLine())
separated = in.nextLine().split(" ");
...
因为在行内我的输入是空格分隔的。
不幸的是,这个过程有数百万行,非常慢,而且扫描仪占用的时间比我的数据处理时间还要多,所以我查看了 java.io 库,发现了很多可能性,但我不确定是哪一个使用(ByteArrayInputStream
、FileInputStream
、BufferedInputStream
、PipedInputStream
)。我应该使用哪一个?
要指定,我的数据是从文本文件中输入的,每行有 4 或 6 个以换行符结尾的单词,我需要一次分析一行,设置(4 或 6)个单词到我可以临时管理的数组。 数据格式:
392903840 a c b 293 32.90
382049804 a c 390
329084203 d e r 489 384.90
...
有没有一种方法可以让扫描仪一次读取 1000 条左右的行并变得高效,或者我应该使用这些数据类型中的哪一种(以最小化速度)?
旁注:在实验中我尝试过:
java.io.BufferedReader stdin = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
while(in.ready())
separated = in.readLine().split(" ");
...
哪个效果很好,只是想知道哪个效果最好,以及是否有任何方法可以一次将 100 行读入数据然后处理所有内容。寻找最佳解决方案的选项太多。
【问题讨论】:
【参考方案1】:你应该用BufferInputStream
包裹你的System.in
,比如:
BufferedInputStream bis = new BufferedInputStream(System.in);
Scanner in = new Scanner(bis);
因为这样可以最大限度地减少对 System.in 的读取量,从而提高效率(BufferedInputStream)。
另外,如果您只是读取行,则不需要扫描器,而是需要读取器(具有 readLine()
和 ready()
方法来获取新行并查看是否还有更多数据需要阅读)。
您可以这样使用它(参见java6 : InputStreamReader 的示例):
(我在BufferedReader
中添加了 32MB 的缓存大小参数)
BufferedReader br = new BufferedReader(new InputStreamReader(System.in), 32*1024*1024);
while (br.ready())
String line = br.readLine();
// process line
来自 InputStreamReader 文档页面:
没有缓冲,每次调用 read() 或 readLine() 可能会导致字节 从文件中读取,转换 变成字符,然后返回, 这可能非常低效。
【讨论】:
嗨,丹,这真的很好用。我现在在没有扫描仪的情况下使用它,但仍然浪费了很多时间,因为读取一行似乎需要时间。有没有一种方法可以让我读取Lines(System.in, 1000) 或类似的东西,然后抓住一堆行,因为我希望(大部分时间)如果我还剩下一行,我应该有数十万行?跨度> 您可以为BufferedReader
构造函数提供一个附加参数以提供缓存大小。这样,如果您想一次缓冲大量数据,您可以提供一个非常大的缓冲区,例如 32 MB。以上是关于比 Scanner 或 BufferedReader 从 STDIN 读取多行数据更快的方式?的主要内容,如果未能解决你的问题,请参考以下文章
JavaI/O:使用InputStreamReader和BufferedReade实现控制器输入输出
Scanner类的next() 和nextLine()的区别