【问题标题】:Java BufferedReader back to the top of a text file?Java BufferedReader 回到文本文件的顶部?
【发布时间】:2008-11-04 17:31:43
【问题描述】:

我目前在同一个文本文件上初始化了 2 个BufferedReaders。当我用第一个BufferedReader 读完文本文件后,我使用第二个从顶部再次通过文件。需要多次通过同一个文件。

我知道reset(),但需要在调用mark()mark() 之前知道文件的大小,我认为我不应该为此烦恼。

想法?包裹?库?代码?

谢谢 TJ

【问题讨论】:

    标签: java file file-io text-files bufferedinputstream


    【解决方案1】:

    仅仅创建一个新的BufferedReader 从顶部读取有什么缺点?如果文件足够小,我希望操作系统会缓存文件。

    如果您担心性能,您是否证明它是一个瓶颈?我只会做最简单的事情,在你有具体理由之前不要担心。我的意思是,您可以将整个内容读入内存,然后对结果进行两次传递,但这再次比使用新阅读器从头开始阅读要复杂得多。

    【讨论】:

      【解决方案2】:

      缓冲读取器旨在按顺序读取文件。您要查找的是java.io.RandomAccessFile,然后您可以使用seek() 将您带到文件中您想要的位置。

      随机存取阅读器是这样实现的:

      try{
           String fileName = "c:/myraffile.txt";
           File file = new File(fileName);
           RandomAccessFile raf = new RandomAccessFile(file, "rw");
           raf.readChar();
           raf.seek(0);
      } catch (FileNotFoundException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
      } catch (IOException e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
      }
      

      "rw" 是一个模式字符,即detailed here

      这样设置顺序存取读取器的原因是,它们可以实现自己的缓冲区,并且事情不能在他们脚下改变。例如,提供给缓冲阅读器的文件阅读器只能由该缓冲阅读器操作。如果有另一个可能影响它的位置,您可能会出现不一致的操作,因为一个阅读器在文件阅读器中提升了它的位置,而另一个阅读器希望它保持不变,现在您使用另一个阅读器并且它位于未确定的位置。

      【讨论】:

        【解决方案3】:

        最好的方法是改变你的算法,这样你就不需要第二遍了。当我不得不处理不适合可用内存的巨大(但并不可怕,即几 GB)文件时,我使用了这种方法几次。

        这可能很难,但性能提升通常值得付出努力

        【讨论】:

        • 您能详细说明一下吗?我有一个 30MB 大的文件,我无法将其全部加载到内存中。我已经对数据进行了排序,现在想直接对文件进行二进制搜索。为此我需要随机寻找。
        • 现在我假设你的意思是 30GB,除非你使用的是非常小的嵌入式硬件(但它会是无盘的)无论如何,磁盘上的随机搜索通常会完全破坏二进制搜索的对数性能。几种选择是 1) 进行顺序访问(是的,在磁盘上顺序搜索可能比二分搜索更快)或 2) 混合方法,例如使用 B-tree en.wikipedia.org/wiki/B-tree 如果这些提示还不够,您可能会想将您的问题作为单独的问题而不是评论提出(请在此处发表评论,并附上问题的链接以 ping 我)
        【解决方案4】:

        关于标记/重置:

        BufferedReader 中的 mark 方法采用 readAheadLimit 参数,该参数限制在标记之后您可以读取多远,然后重置变得不可能。重置实际上并不意味着文件系统 seek(0),它只是在缓冲区内寻找。引用 Javadoc:

        readAheadLimit - 限制在保留标记的同时可以读取的字符数。读取这么多字符后,尝试重置流可能会失败。大于输入缓冲区大小的限制值将导致分配一个大小不小于限制的新缓冲区。因此,应谨慎使用较大的值。

        【讨论】:

          【解决方案5】:

          “关于 BufferedReader 中的 mark() 和 reset() 的整个过程都带有糟糕的设计味道。”

          你为什么不扩展这个类并让它在构造函数()中做一个标记(),然后在topOfFile()方法中做一个seek(0)。

          BR,
          ~A

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-09-07
            • 1970-01-01
            • 2014-02-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-17
            • 2021-12-21
            相关资源
            最近更新 更多