【问题标题】:updating line in large text file using scala使用scala更新大文本文件中的行
【发布时间】:2013-07-18 09:04:30
【问题描述】:

我有一个大约 43GB 的 .ttl 大文本文件,其中包含以下形式的三元组:

<http://www.wikidata.org/entity/Q1001> <http://www.w3.org/2002/07/owl#sameAs> <http://la.dbpedia.org/resource/Mahatma_Gandhi> .
<http://www.wikidata.org/entity/Q1001> <http://www.w3.org/2002/07/owl#sameAs> <http://lad.dbpedia.org/resource/Mohandas_Gandhi> .

我想找到最快的方法来更新文件中的特定行而不重写所有下一个文本。通过更新或删除它并将其附加到文件末尾

要访问特定行,我使用以下代码:

val lines = io.Source.fromFile("text.txt").getLines
val seventhLine = lines drop(10000000) next

【问题讨论】:

  • 它似乎使用了结构如此弱的“文本文件”(这显然是 不是 文本,它只是让你误以为它是),因为这种数据存储似乎就像一个明显的错误。还要记住,将这些数据视为文本并编写代码来操作“行”或Strings 将意味着您将在系统中移动至少 172 GB 的数据,因为每个 JVM char / Scala Char 是两个字节,因此读取的每个字节都必须在读取时复制到 char 数组,在写入时复制回一个字节。
  • 你应该考虑 SQLite。通过一些仔细的调整,您可以避免重新发明轮子。

标签: scala large-data bigdata


【解决方案1】:

如果您想使用文本文件,请考虑为每行/记录设置一个固定的长度/记录大小。

这样,您可以使用RandomAccessFileseek 来按数字显示每行的确切位置:您只需寻找line * LineSize,然后更新它。

如果您必须插入一个新行,它不会真正有帮助。其他限制是:文件大小会变大(因为记录长度是固定的),并且总会有一个记录太大。

至于初始转换:

  • 获取当前文件的最大行长,例如加10%。
  • 现在您必须转换文件一次:从文本文件中读取一行,并将其转换为固定大小的记录。
  • 您可以使用像| 这样的特殊字符来分隔字段。如果可能,请使用 ; 之类的东西,这样您就可以得到一个 .csv 文件
  • 我建议用空格填充剩余的空间,这样它看起来仍然像一个文本文件,您可以使用 shell 实用程序对其进行解析。
  • 您可以使用\n 来终止记录。

例如

http://x.com|http://x.com|http://x.com|...\n

http://x.com;http://x.com;http://x.com;...\n

末尾的每个. 代表一个空格字符。所以它仍然以某种方式与“普通”文本文件兼容。


另一方面,查看您的数据,考虑使用像 Redis 这样的键值对数据存储:您可以使用行号或第一个 URL 作为键。

【讨论】:

  • 它应该是一个小任务,应该是可移植的,不需要为 redis 安装新的基础设施和库,我选择 RandomAccessFiles,但行不是固定长度,最好的方法是什么固定长度我应该添加什么填充?
  • @Hady Elsahar 我已将答案更新为有关初始转换的可能情况。
猜你喜欢
  • 2013-01-07
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
相关资源
最近更新 更多