是否可以在C#中读取和写入相同的文本文件

时间:2018-04-02 23:49:18

标签: c# delphi streamreader streamwriter

情况如下。我有超过1500个SQL(文本)文件,其中包含“在CREATE TABLE语句之后向某些用户授予某些权限的某些权限。我需要从原始文件中删除它们并将GRANT语句放在它们自己的文件中。有时候Grants在一行上,有时它们分成多行。例如:

  GRANT SELECT ON XYZ.TABLE1 TO MYROLE1 ;
  GRANT
  SELECT ON XYZ.TABLE1 TO MYROLE2 ;
  GRANT
  DELETE,
  INSERT,
  SELECT,
  UPDATE ON XYZ.TABLE1 TO MYROLE3;

我正在阅读文件,直到我到达GRANT,然后构建一个包含GRANT到分号的文本的字符串,然后我将其写入另一个文件。我有一个我用Delphi(Pascal)编写的应用程序,这个部分很棒。我想要做的是在我阅读并处理了我想要的行之后,我想从原始文本文件中删除该行。我不能在Delphi中这样做。唯一的解决方案是逐行读取文件并将文件写回另一个文件,不包括我不想要的行,同时还将GRANTS写入另一个文件。然后删除原始文件并重命名新文件。处理过多和风险太大。

我在C#中使用了StreamReader和StreamWriter,但它似乎与Delphi类似。我可以读或我可以写,但我不能同时对同一个文件做两个。

我将不胜感激任何建议或建议。

由于

1 个答案:

答案 0 :(得分:2)

如果您认为在没有您不想要的行的情况下生成新的临时文件并且替换原始,则“处理和风险太大”:那么请考虑您希望的备选方案实现。

    Line 1
    Line 2
    Delete this line
+-->Line 4
|   Line 5
|
+- Read position marker after reading line to be deleted

如果您在阅读时立即删除该行,则必须将后面的行移回到删除第3行后留下的“空白区域”。为了确保您下次阅读“第4行”,您必须回溯您的读取位置标记。什么是回溯的正确数量? 可变长度的“行”,或删除行的字符数

您认为“风险”选项实际上是安全选项!

如果您想在处理时删除,可以使用抽象来给您留下印象。但是你失去了流处理的好处,并且不会真正消除你首先担心的任何风险。

E.g。将整个文件加载到字符串列表中;例如数组,向量或TStringList(在Delphi中)。迭代列表并删除不需要的项目。最后将列表保存回文件。

这种方法有以下缺点:

  • 潜在的高内存开销,因为您加载整个文件而不是流的小缓冲区。
  • 由于您的工作 all-or-nothing ,您将面临无法恢复的中间过程失败的风险。
  • 您必须处理您选择用于保存字符串列表的特定容器的细微差别。
    • 在某些情况下(例如TStringList),您可能仍需要以与之前描述类似的方式回溯您的位置标记。
    • 对于数组,每次删除具有巨大性能成本的内容时,您都必须将所有行复制回1个位置。 (同样的情况发生在TStringList,虽然它对你来说是隐藏的。)
    • 修改列表时,某些容器的迭代器无效。这意味着在任何情况下都必须复制到没有“删除行”的新列表。 更多内存开销。

总之,请使用 安全选项 。使用单独的读写流;写入临时文件,完成后重命名。 它会让你头疼。