如何删除记录并继续阅读文件?

时间:2014-06-11 19:59:11

标签: java file

我必须阅读一个有超过一百万条记录的顺序文件。我必须阅读每一行/记录,并且必须从文件中删除该记录/行并继续阅读。

在没有使用临时文件或创建/重新创建同名新文件的情况下,没有找到关于如何做到这一点的任何示例。

这些是文本文件。每个文件大约0.5 GB,每个文件中有超过一百万行/条记录。

目前我们正在将所有记录复制到内存中,因为如果在处理文件的过程中发生任何事情,我们不想重新处理任何记录。

4 个答案:

答案 0 :(得分:4)

假设有问题的文件是一个简单的顺序文件 - 你不能这样做。在Java文件模型中,删除文件的一部分意味着在删除点之后删除所有文件。

一些替代方法是:

  • 在您的流程中复制文件,省略要删除的部分。这是正常的做法。
  • 使用您知道从未在文件中出现的某个值覆盖要删除的文件的部分,然后在以后复制该文件,删除标记的部分。
  • 将整个文件存储在内存中,根据需要进行编辑,然后重新编写。仅仅因为你有一百万条记录并不能让它变得不可能。如果您的文件是0.5GB,如您所说,那么这种方法几乎肯定是可行的。
  • 每次删除某些记录时,请将删除后的文件的所有内容复制到新位置。这将非常低效且容易出错。

除非您可以将文件存储在内存中,否则使用临时文件效率最高。这就是每个人都这样做的原因。

如果这是某种数据库,那那就是一个完全不同的问题。

编辑:我回答了这个问题。评论表明,用户想要做的是使用删除来跟踪哪些记录已被处理。如果是这种情况,可以采用更简单的方法。一种好方法是编写一个文件,其中只包含已处理文件的字节数(或记录数)的计数。如果处理器崩溃,请通过删除已处理的记录来更新文件,然后重新开始。

答案 1 :(得分:1)

文件是非结构化的字节流;没有记录结构。你不能删除" a" line"来自非结构化的字节流。

您需要使用的基本算法是:

  1. 创建临时文件。
  2. 打开输入文件
  3. 如果在文件的末尾,请转到第7行
  4. 从输入文件中读取一行
  5. 如果不删除该行,请将其写入临时文件
  6. 转到第3行
  7. 关闭输入文件。
  8. 关闭临时文件。
  9. 删除(或只是重命名)输入文件。
  10. 重命名(或移动)临时文件以具有输入文件的原始名称。

答案 2 :(得分:0)

有一个类似的问题,"Java - Find a line in a file and remove"

基本上他们都使用临时文件,这样做没有害处。那么为什么不这样做呢?它不会对您的性能产​​生太大影响,可以避免一些错误。

答案 3 :(得分:0)

为什么不是一个简单的sed -si '/line I want to delete/d' big_file