【问题标题】:Check for fixed-length marker at end of file检查文件末尾的固定长度标记
【发布时间】:2011-02-27 21:55:42
【问题描述】:

我有一个应用程序,之后我的任务是清理。应用程序本身相对简单 - 它运行 SQL 查询,使用 Web 服务,并将结果发送到日志文件。我的工作是在应用程序完成后将文件归档到我们的 NAS。它会专门锁定文件,直到处理完它们,所以它增加了一点复杂性。我也不允许触摸应用程序,只能触摸日志。无论如何,我的应用程序相当简单:

  1. 检查文件是否可以打开(捕获 IOException),如果没有抛出异常,则在 bool[] 中将其标记为可访问。
  2. 遍历标记为 true 的文件数组,使用 ReadLine 方法将文件的每一行读入 StreamReader。因为应用程序偶尔会打嗝并且没有完成,所以我不能简单地使用 IOException 来判断文件是否完成 - 我必须实际解析文本。
  3. 如果找到指示完成的文本,请压缩文件,将归档文件加载到 NAS,并删除原始文件。

我的代码有效,只是非常耗时(每个日志文件大约 500 MB)。我对改进的想法涉及从文件底部而不是从顶部开始搜索,但 StreamReader 不支持这种方法。我不能使用 ReadToEnd 方法然后反向读取,因为这只会引发内存不足异常。有什么想法可以加快日志文件的解析速度吗?

【问题讨论】:

  • 你知道解析文件是慢的部分吗?不压缩、复制到 NAS、删除或尝试打开文件(并且可能失败)所有这些听起来都需要一段时间
  • 好问题。是的,解析绝对是执行中耗时的部分。我将代码分成单独的函数并在每个函数上放置断点。压缩大约需要 30 到 45 秒,解析可能需要两个小时以上。
  • @monkeyninja:你看过我链接的问题了吗?那里的答案有用吗?
  • 我做到了。看起来它肯定会起作用,我唯一担心的是它的复杂性。在我使用完归档工具后,我将把工作交给团队中资历较浅的成员,因此我试图让这里的实现尽可能容易理解。

标签: c# parsing streamreader


【解决方案1】:

我假设您在文件末尾查找单个标记以确定它是否已完成?如果是这样,我还假设标记的长度已知,例如单个字节或 3 个字节的序列等。

如果上述假设正确,您可以打开 FileStream,Seek 到文件末尾减去预期的标记长度读取字节,如果标记存在且完整,则您知道您可以处理文件。

可以使用以下代码来完成 -3 个字节的查找

// Seek -3 bytes starting from the end of the file
fileStream.Seek(-3, SeekOrigin.End);

【讨论】:

  • 查找可能是比顺序读取更昂贵的操作,并且执行多次查找可能非常慢。
  • 这是我还没有尝试过的东西,所以值得一试。我将尝试实现搜索,看看是否可以加快速度。谢谢大家。
  • @josephj1989,您是说逐行读取 500 MB 文件或在内存友好的块中读取到末尾比直接查找到末尾要快吗?以及为什么要多次查找,我的假设是标记位于文件末尾,所以只有一次查找。
  • 主要是为来这里寻找已经编写好的反向行阅读器的人:这是传奇人物 Jon Skeet 所写的:stackoverflow.com/a/452945/2127371
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 2016-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-23
相关资源
最近更新 更多