簡體   English   中英

刪除XML文件C#.NET中的文本行

[英]Remove text line in XML file C# .NET

我需要編寫應用程序來刪除非常大的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

我如何解決我的代碼以使新文件與舊文件相同,僅沒有特定行?

首先,為什么要繼續打開和關閉輸出文件? 保持打開狀態。

其次,讀取塊(可能導致“刪除行”被拆分成塊)和寫入行是一種奇怪的混合。

但我希望您的問題有三方面:

  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);
  }
}

注意:將 XML作為文本處理可能會導致XML損壞(不存在“無效XML”之類的東西:文檔是有效XML或不是XML,只是看起來有點像XML)。 因此,任何此類方法都必須謹慎處理。 正確的答案是使用流API( XmlReaderXmlWriter )作為XML處理以避免將整個文檔解析為一個。

我嘗試通過XmlTextReader進行此操作,但在讀取文件時遇到了system.xml.xmlexception,截圖: https : //images82.fotosik.pl/622/d98b35587b0befa4.jpg

碼:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM