【问题标题】:Mapping a flat text file映射平面文本文件
【发布时间】:2011-12-04 07:48:59
【问题描述】:

在文本文件中,行由每行末尾的 \n 检测。为此,需要读取整个文件,这对于大文件(比如 2GB)来说是个大问题。我正在寻找一种无需遍历整个文件即可读取单行的方法(尽管我知道这应该是一个复杂的过程)。

  1. 我知道的第一种方法是使用带偏移的 fseek();但不实用。
  2. 创建键/值的平面文件;但我不确定是否有办法避免将整个加载到 RAM 中(应该类似于在 php 中读取数组)。
  3. 或者,我们可以在每行的开头制作一些数字以供读取。我的意思是,是否可以通过跳过行内容(转到下一行)来读取行首的第一个数字。

    768| line content is here
    769| another line
    770| something
    

如果只读取第一个数字,即使是大文件,应该读取的总数据也不多。

【问题讨论】:

  • 您始终可以在循环中逐行读取整个文件,提取起始数字并丢弃剩余行。但是,您需要注意性能。对于 2 GB 的文件,这可能需要相当长的时间。
  • 我正在寻找的只是避免逐行读取整个文件。
  • 您需要阅读可以在行号上索引的特定行吗?如果是这样,只需进行二进制搜索。读取(比如说)文件中间的 200 个字符以找出行号。然后重复任一半,直到你到达正确的线。
  • 我的猜测是你必须阅读整个文件 - 或者至少直到你找到你感兴趣的行 - 除非所有行都有相同的长度(我可以看到他们这样做不是)。

标签: php database text flat-file


【解决方案1】:

或者您可以最初为您的文本文件编制索引,然后根据您的索引文件继续您的日常操作,即提取单个文件行。您可以找到如何索引您的文本文件 herehere为文本文件编制索引与为 CSV 或可变记录文件编制索引没有什么不同。

【讨论】:

    【解决方案2】:

    我认为没有简单的方法可以做你想做的事。记录的长度是可变的,不能提前确定长度,对吧?

    如果文件始终相同(或至少不经常修改),我会将其放入数据库,或至少创建索引文件(记录号:偏移量)并使用该 fseek()

    【讨论】:

    • 您对快速创建和更新索引文件有何建议?
    • 如果您逐行编写文件,正如您在下面的评论中提到的,您可以并行创建索引。只需累积偏移量(先前的数据长度)并将文件固定长度记录(例如使用 pack)中的每一行存储到索引文件中。您可以将其全部包装在单个类中并在任何地方使用。要读取字符串,您只需计算索引中的偏移量:linenum * recordlenght,fseek 并读取 recordlength 字节,解包,fseek 在文本文件中并读取该行。它可能看起来很复杂,但却是一种常用的索引方法。
    【解决方案3】:

    您是否需要阅读可以在行号上索引的特定行?如果是这样,只需进行二进制搜索。读取(比如说)文件中间的 200 个字符以找出行号。然后重复任一半,直到你到达正确的线。

    【讨论】:

    • 线条是可变长度的。如何通过读取文件中间的 200 个字符来找出行号?
    • 如果在 200 个字符中找不到行号,请继续向前(或向后)阅读,直到找到为止。然后当你确实有一个行号时,继续使用二进制搜索算法:)
    猜你喜欢
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多