【问题标题】:Is there an elegant way to parse a text file *backwards*? [duplicate]有没有一种优雅的方式来解析文本文件*向后*? [复制]
【发布时间】:2011-07-31 16:07:15
【问题描述】:

可能重复:
How to read a file from bottom to top in Ruby?

在编写我的 Ruby 程序的过程中,我有一个 Eureka Moment,如果我能够向后而不是向前解析文本文件,那么编写起来会简单得多。

看起来很简单,只需将文本文件逐行读取到一个数组中,然后将这些行向后写入一个文本文件,向前解析这个临时文件(现在实际上 be 向后)进行任何必要的更改,将结果行重新编目到一个数组中,然后再次将它们向后写入,恢复原始方向,然后将修改保存为新文件。

虽然理论上可行,但我在实践中看到了几个问题,其中最大的问题是如果文本文件的大小非常大,单个数组将无法一次容纳整个文档.

有没有更优雅的方式来完成向后读取文本文件?

【问题讨论】:

  • 你必须用 Ruby 做所有事情吗?如果不是,我只会使用tac (ss64.com/bash/tac.html) 将反转的文件通过管道传输到 Ruby 脚本中(并且可能第二次再次反转输出。

标签: ruby


【解决方案1】:

如果您不使用大量 UTF-8 字符,则可以使用 Elif 库,其工作方式与 File.open 类似。只需加载 Elif 并将 File.open 替换为 Elif.open

Elif.open('read.txt', "r").each_line{ |s|
    puts s
}

这是一个很棒的库,但我现在遇到的唯一问题是它在以 UTF-8 结尾的行有几个问题。我现在必须重新考虑一种迭代文件的方法


其他详情

当我在谷歌上搜索 UTF-8 反向文件读取的方法来回答这个问题时。我找到了一个文件库已经实现的方法:

要向后读取文件,您可以尝试使用 ff 代码:

File.readlines('manga_search.test.txt').reverse_each{ |s|
   puts s
}

这也可以做得很好

【讨论】:

  • File.readlines('manga_search.test.txt').reverse_each 为我工作,谢谢。
【解决方案2】:

Ruby 数组没有软件限制。不过有一些内存限制:Array size too big - ruby

如果您可以将所有内容读入内存、在内存中操作并将其写回磁盘,您的方法会运行得更快。当然,假设文件适合内存。

【讨论】:

  • 我将所有内容都读入内存没有问题,但我仍然需要能够向后削减文件。
  • 一旦你有了一个行/字符串数组,你就可以从最后一个元素开始遍历一个数组,然后倒退。这就是你的烦恼吗?
  • 啊,我明白了。不,我误解了你的建议。现在我明白了。
【解决方案3】:

假设您的行平均宽度为 80 个字符,并且您想要阅读 100 行。如果您希望它高效(而不是用最少的代码实现),然后从末尾返回 80*100 字节(使用带有“相对于末尾”选项的 seek),然后读一行(这可能是部分行,所以把它扔掉)。通过tell 记住您当前的位置,然后阅读所有内容直到最后。

您现在的内存中的行数多于或少于 100 行。如果小于,则返回 (100+1.5*no_of_missing_lines)*80,并重复上述步骤,但只读取行数,直到您到达之前记住的位置。冲洗并重复。

【讨论】:

    【解决方案4】:

    如何直接到文件末尾并在每个字符上向后迭代,直到到达换行符,读取该行等等?不优雅,但肯定有效。

    示例:https://gist.github.com/1117141

    【讨论】:

    • 不过,我不确定这在缓冲方面是否有效。我的猜测是,每次执行 readchar 时,这段代码都会填充缓冲区。更好的方法可能是一次读取 BUF_SIZE 字符并从那里处理它。
    【解决方案5】:

    我想不出一种优雅的方式来做如此不寻常的事情,但您可能可以使用file-tail 库来做到这一点。它使用 Ruby 中的随机访问文件来向后读取它(您甚至可以自己做,在this link 寻找随机访问)。

    【讨论】:

      【解决方案6】:

      您可以向前遍历整个文件,只存储每个 \n 的字节偏移量,而不是存储每行的完整字符串。然后你向后遍历你的偏移数组,并可以使用 ios.sysseek 和 ios.sysread 从文件中获取行。除非您的文件真的很大,否则应该可以缓解内存问题。

      诚然,这绝对没有通过优雅测试。

      【讨论】:

        猜你喜欢
        • 2014-05-13
        • 2011-09-18
        • 2010-09-07
        • 2019-03-24
        • 2010-09-10
        • 1970-01-01
        相关资源
        最近更新 更多