在没有循环的情况下在某一行中写入文件

本文关键字:一行 文件 循环 情况下 | 更新日期: 2023-09-27 18:27:12

在c#中,我想访问文件的某一行来重写它,而不更改其余部分

using (StreamWriter writer = new StreamWriter(myfile))
{
    for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
    {
        if (currentLine == Linetoedit)
        {
             writer.WriteLine(stufftowrite);
             return;
        }
        else
        {
            //do nothing
        }
    }
}

问题是文件可能很大,这让我担心系统会因此而变慢。有什么解决方案可以避免循环并以更直接的方式访问文件中所需的行?

在没有循环的情况下在某一行中写入文件

从听起来,这是不可能的。你不能根据那里的字符随机跳到一个位置,所以你必须通读,直到找到要替换的行,从而形成一个循环。在没有循环的情况下,唯一的方法是如果行的长度相同,那么你会说"我想要行号x",因此你想查找x * [line length]。所以这很简单,但也是一个相对受限的设置。

也就是说,如果你只想更换一条线路,你可能无论如何都要担心线路长度。您不能"插入"到流中,只能选择一个起始位置并写出随后的字节。因此,如果您试图将长度为40个字符的一行替换为长度为60的一行,则最终会在下一行中写入18个(60 - 40 - "'r'n".Length)字符。

所以这里基本上有两种情况:

  1. 恒定线长度:在流中寻找,从而否定循环
  2. 可变行长度:您必须循环,但这没关系,因为您无论如何都必须重写替换行之后的任何数据

我想我也可以考虑第三种情况,在这种情况下,你可以保证你的替换字符串与原始字符串的长度完全相同。然后你只需要循环到那一行。但这实际上只是上述两者的总和。

显然,有一些更好的方法(可以说)来执行这一功能。至少用更简单的方法。但我不认为这是你在这里要求的。

例如,如果你真的非常渴望性能,并且文件以某种方式进行了排序或索引,你可以编写一个简单的二进制搜索来查找文件。尽管对于一个真正的文件来说,这甚至只是微不足道的好处。

不过,老实说。除非你处理的是一个"真正的大文件",否则我会有点惊讶地看到这些文件花了这么多时间。如果你是这样的话,那么以一种可以允许的方式来构建你的应用程序可能是值得的。IO本身就很昂贵,因此很难像我们有时想要的那样进行优化,所以你可能想要一个进度条或等效的进度条来向用户显示正在发生的事情。

如果不重写文件的其余部分,就不能在文本文件的中间插入行。只有当使用具有固定长度记录的二进制文件时,才可能进行重写。这是磁盘存储的限制,磁盘存储在内部以块的形式存储文件。

有关详细信息,请参阅以下讨论:使用Win32 API 以特定偏移量将文本插入文件