读取(可能很大)文本文件而不用Java读取内存?

时间:2015-05-26 16:45:22

标签: java text-files

我正在开发一个程序来读取各种文本文件并显示它们,而不必将整个文件读取到内存中。

我希望程序做什么的简要说明:

  1. 假设有一个3000行的文件。
  2. 一次显示50行
  3. 允许用户向下滚动以读取更多行,但这些行是从阅读器实时加载的。 现在未显示的更多行不会存储在内存中。
  4. 允许用户向上滚动以阅读上一行,但这些行也会实时加载或至少以与向前阅读相似的方式加载。
  5. 我想要的是定制程序以节省内存并处理大文件而不会失败。我在看BufferedReaders,但似乎没有一种可靠的向后遍历方式。我最初看的是mark()和reset()是如何运行的,但我找不到可以设置多个标记的类。

    我想知道是否有人可以帮助我,并给我一些我可以使用的有用课程的指示。我开始讨论像ByteBuffers和CharBuffers这样的NIO课程,但是我很想知道如何实现它们以实现我想要完成的目标。

    谢谢!

2 个答案:

答案 0 :(得分:3)

回到计算机的古代(1980年代),这正是我们处理大型文件以便显示的原因。

基本上,您需要一种可以从文件中读取指定行的输入方法。像

这样的东西
List<String> block = readFile(file, 51, 100);

将读取文件的第51行到第100行。

我认为有两种方法可以实现这一目标。

  1. 每次从文件的开头读取,跳过第n个记录并检索50个(或其他一些数字)字符串。

  2. 读取文件一次,然后将其分解为长度为50(或其他数字)的x文件。读取您的临时文件以获取字符串。

  3. 无论哪种方式,你都会在内存中保留3个块;当前块,前一个块和下一个块。

    当您向前移动字符串时,当前块将成为上一个块,下一个块将成为当前块,并且您将读取新的下一个块。

    当您向后移动字符串时,当前块将成为下一个块,前一个块将成为当前块,并且您将读取新的上一个块。

答案 1 :(得分:3)

对文件的随机访问是available in Java。因此,您可以非常轻松地浏览文件的字节,并且一次将文件区域映射到内存。

您可以对可读区域实施Deque<E>实施。然后,您可以从两端添加/删除数据块或“行”,以表示可视数据滚动。

如果“行”定义了符合可视显示宽度的字符(例如控制台窗口),那么您可能只是继续加载下一个x字节/字符,并删除以前的x字节/字符。

否则,您可能需要提前扫描,并构建有关该文件的一些元数据,记下行的位置或文件中的其他有趣结构。然后,您可以使用此元数据快速导航文件。