在c#

时间:2017-12-27 20:12:48

标签: c# text io

进行以下操作:

  1. 打开文本文件
  2. 使用新字符搜索并替换所有搜索字符
  3. 我想在c#中实现上述目标,这是我的代码:

    using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
    {
        using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
        {
            string line;
    
            while ((line = sr.ReadLine())!= null)
            {               
                if (!line.Contains("before"))
                {
                    sw.WriteLine(line);
                }
    
                else if (line.Contains("before"))
                {
                    sw.WriteLine(line.Replace("before", "after"));
                }
            }
        }
    }
    

    基本上,上面的代码将生成一个带有所需替换操作的新文件,但正如您所看到的,我正在做的方法是读取原始文件的每一行并写入新文件。这可以实现我的目标,但它可能有系统IO问题,因为它是为每一行读写。另外,我无法首先读取所有行到数组,然后写入,因为文件很大,如果我尝试写入string[],则替换all,然后将数组写入文件,将带来内存超时问题。

    有什么方法可以找到特定的线条,只需更换这些线条并保留其余部分?或者解决上述问题的最佳方法是什么?感谢

4 个答案:

答案 0 :(得分:1)

一般来说,你正在做的是正确的,可能后面有一些重命名来替换原始文件。如果确实要替换原始文件,则应将原始文件重命名为临时名称,将新文件重命名为原始名称,然后保留或删除原始文件。您必须处理与临时名称的冲突以及所有重命名中的错误。

考虑使用五个字符的字符串替换六个字符的字符串 - 如果您回写原始文件,您将如何处理额外的字符?文件作为原始数据字节存储在磁盘上,没有"文本"磁盘上的文件。如果用较长的字符串替换字符串会怎么样 - 然后可能需要移动文件的其余部分以腾出空间来写更长的行。

您可以将磁盘上的文件想象为方框中的方格纸上写的字母。每行的结尾用特殊字符(或字符 - 在Windows中,即CRLF)标记,字符水平填充所有框。如果您试图替换方格纸上的文字,则必须删除并重写大量字母。在新表上书写将是最简单的。

答案 1 :(得分:1)

嗯,你的方法基本上没问题......但是我不会检查该行是否包含单词before ......权衡利弊是不够的:

using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
{
    using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
    {
        String line;

        while ((line = sr.ReadLine()) != null)
            sw.WriteLine(line.Replace("before", "after"));
    }
}

答案 2 :(得分:1)

我不知道您担心的IO问题,但您的代码应该可以正常工作。您可以按如下方式更简洁地编写代码:

using (StreamReader sr = new StreamReader(@"S:\Personal Folders\A\TESTA.txt"))
{
    using (StreamWriter sw = new StreamWriter(@"S:\Personal Folders\A\TESTB.txt"))
    {
        while ((string line = sr.ReadLine())!= null)
        {
            sw.WriteLine(line.Replace("before", "after"));
        }
    }
}

这会运行得更快,因为它每行只搜索一次“之前”。默认情况下,StreamWriter会缓冲您的写入,并且每次调用WriteLine时都不会刷新到磁盘,并且文件IO在操作系统中是异步的,因此不要过于担心IO。

答案 3 :(得分:-1)

请尝试以下操作:

else if (line.Contains("before"))
{
    sw.WriteLine(line.Replace("before", "after"));
    sw.Write(sr.ReadToEnd());
    break;
}