代码之家  ›  专栏  ›  技术社区  ›  Richard Anderson

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

  •  0
  • Richard Anderson  · 技术社区  · 7 年前

    情况是这样的。我有1500多个SQL(文本)文件,其中包含“在CREATE table语句之后,向某些用户授予某些表上的某些权限。我需要将它们从原始文件中删除,并将GRANT语句放在自己的文件中。有时授予位于一行上,有时则拆分为多行。例如:

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

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

    我研究了在C中使用StreamReader和StreamWriter,但它似乎与Delphi的情况类似。我可以读或写,但我不能同时对同一个文件执行这两项操作。

    如有任何建议,我将不胜感激。

    谢谢

    1 回复  |  直到 7 年前
        1
  •  2
  •   Disillusioned    7 年前

    如果您认为 生成一个没有不需要的行的新临时文件并替换原始文件 :然后考虑您希望实现的替代方案。

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

    如果您在阅读时立即删除该行,则在删除第三行后,后面的行必须移回留下的“空白”中。为了确保您下次阅读“第4行”,您必须 回溯 您的读取位置标记。回溯的正确金额是多少?“一行” 可变长度 ,或 字符数 删除行的?

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


    如果您想在处理过程中删除,可以使用一个给您留下这种印象的抽象。但是您失去了流处理的好处,并且没有 真正地 首先消除您担心的任何风险。

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

    这种方法有以下缺点:

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

    总之,采取 安全选项 。使用单独的读写流;写入临时文件,完成后重命名。 这会让你省去头痛。