我有一个行N
行的大文本文件。现在我必须在i
次迭代中阅读这些行。这意味着我必须在一次迭代中读取n = Math.floor(N/i)
行。现在,在每次迭代中,我必须填充n
长度的字符串数组。所以基本的问题是我应该如何在最佳时间内阅读n
行?最简单的方法是使用BufferedReader
并使用BufferedReader.readLine()
一次读取一行,但如果n
太大,则会显着降低性能。有没有办法一次准确读取n
行?
答案 0 :(得分:1)
要从文本文件中读取n
行,从系统的角度来看,除了必要的阅读尽可能多的字符之外别无他法,直到您看到n
行尾分隔符(除非文件已被预处理以检测这些,但我怀疑这是允许的。)
据我所知,世界上没有任何文件I / O系统支持“直到nth
某个字符出现”之前的函数,也不支持“n
以下行”(但我可能错了。)
如果你真的想最大限度地减少I / O函数调用的次数,那么你的最后一种方法是使用块I / O,你可以用它来读取一个“页面”(比如预期的n
倍或最大线长度),并自己检测行尾。
答案 1 :(得分:0)
我同意Yves Daoust的回答,除了推荐的段落
如果你真的想最小化I / O函数调用的数量,你的最后一种方法就是块I / O,你可以用它来读取一个“页面”(比如长度n倍于预期或最大行长度) ),并自己检测行尾。
没有必要“自己检测行尾”。像
这样的东西new BufferedReader(new InputStreamReader(is, charset), 8192);
创建一个缓冲区为8192个字符的阅读器。问题是这对于读取块中的数据有多大用处。为此,我需要byte[]
,其间有一个sun.nio.cs.StreamDecoder
我尚未调查过。
一定要使用
new BufferedReader(new InputStreamReader(new BufferedInputStream(is, 8192), charset));
所以你得到一个byte[]
缓冲区。
请注意,8192是BufferedReader
和InputStreamReader
的默认大小,因此将其删除在上面的示例中不会改变任何内容。请注意,使用多更大的缓冲区是没有意义的,甚至可能对性能有害。
到目前为止,你得到了所需的所有缓冲,这应该足够了。如果没有,您可以尝试:
\n
终止时,您可以在文件内容中查找(byte) \n
而不对其进行解码(除非您使用了一些异国情调的Charset
)。