【问题标题】:Remove text line in XML file C# .NET删除 XML 文件 C# .NET 中的文本行
【发布时间】:2017-11-05 23:30:23
【问题描述】:

我需要编写应用程序来删除非常大的 XML 文件(大约 3.5 GB)中的特定文本行。

我写了这段代码:

    string directoryPath;

    OpenFileDialog ofd = new OpenFileDialog();

    private void button1_Click(object sender, EventArgs e)
    {
        ofd.Filter = "XML|*.xml";
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            directoryPath = Path.GetDirectoryName(ofd.FileName);
            textBox2.Text = directoryPath;
            textBox1.Text = ofd.SafeFileName;
        }
    }

    private void Replace()
    {
        StreamReader readerFile = new StreamReader(ofd.FileName, System.Text.Encoding.UTF8);

        while (!readerFile.EndOfStream)
        {
            string stringReplaced;
            string replaceResult = textBox2.Text + "\\" + "replace_results";
            Directory.CreateDirectory(replaceResult);
            StreamWriter writerFile = new StreamWriter(replaceResult + "\\" + textBox1.Text, true);
            StringBuilder sb = new StringBuilder();
            char[] buff = new char[10 * 1024 * 1024];
            int xx = readerFile.ReadBlock(buff, 0, buff.Length);
            sb.Append(buff);
            stringReplaced = sb.ToString();
            stringReplaced = stringReplaced.Replace("line to remove", string.Empty);
            writerFile.WriteLine(stringReplaced);
            writerFile.Close();
            writerFile.Dispose();
            stringReplaced = null;
            sb = null;
        }


        readerFile.Close();
        readerFile.Dispose();
    }

    private void button2_Click(object sender, EventArgs e)
    {
        if (!backgroundWorker1.IsBusy)
        {
            backgroundWorker1.RunWorkerAsync();
            toolStripStatusLabel1.Text = "Replacing in progress...";
        }
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            Replace();
            toolStripStatusLabel1.Text = "Replacing complete!";
        }
        catch
        {
            toolStripStatusLabel1.Text = "Error! Replacing aborted!";
        }
    }
}

它可以工作,但效果不佳,因为新文件(删除行之后)比原始文件大,并且在新文件的末尾添加了一些垃圾(很多点),截图:

https://images81.fotosik.pl/615/873833aa0e23b36f.jpg

我如何修复我的代码以使新文件与旧文件相同,只是没有特定的行?

【问题讨论】:

    标签: c# xml text replace


    【解决方案1】:

    首先,为什么要不断打开和关闭输出文件?保持打开状态。

    第二次读取块——这可能导致“要删除的行”被分割成块——而写入行是一种奇怪的混合。

    但我预计您的问题是三个方面:

    1. 你没有设置输出文件的编码。

    2. 当您读取缓冲区 (10MB) 时,您可能会读取更少的字符 - 从 ReadBlock 返回。但是你总是写完整的块。限制写入以匹配读取量(更新但替换)。

    3. ReadBlock 将包括行尾,但WriteLine 将添加它们:要么在块上工作,要么在行上工作。混合只会产生问题(并避免上述第二个问题)。

    这导致代码类似于:

    using (var rdr = OpenReadFile(...))
    using (var wtr = OpenWriteFile(...)) {
      string line;
      while ((line = rdr.ReadLine()) != null) {
        line = line.Replace(x, y);
         str.WriteLine(line);
      }
    }
    

    NB 将 XML 作为文本处理可能会导致 XML 损坏(没有“无效 XML”之类的东西:文档要么是有效的 XML,要么不是 XML,只是看起来有点像它可能是 XML)。因此,任何此类方法都需要谨慎处理。 “正确”的答案是使用流 API(XmlReaderXmlWriter)作为 XML 进行处理,以避免将整个文档解析为一个。

    【讨论】:

    • 我怎样才能只在没有内存不足异常的行上进行这项工作?你能给我代码吗? :)
    • @gos:中心循环应该是:读行、处理、写行。您在内存中一次只能有一行。
    • @gos:查看扩展答案。
    【解决方案2】:

    我尝试通过 XmlTextReader 执行此操作,但在读取文件时出现 system.xml.xmlexception,截图:https://images82.fotosik.pl/622/d98b35587b0befa4.jpg

    代码:

    XmlTextReader xmlReader = new XmlTextReader(ofd.FileName);
    XmlDocument doc = new XmlDocument();
    doc.Load(xmlReader);
    

    【讨论】:

      猜你喜欢
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多