2

是)我有的:

一个大型 XML 文件,内容价值近 100 万行。内容示例:

<etc35yh3 etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>
<etc123 etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>
<etc15y etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>

^ 重复 900k 左右行(内容当然会改变)

我需要的:

在 XML 文件中搜索"<etc123". 一旦找到,将该行连同它下面的所有行一起移动(写入)到一个单独的 XML 文件中。

是否建议对搜索部分使用诸如 File.ReadAllLines 之类的方法?对于写作部分,你们会推荐什么。据我所知,逐行不是一种选择,因为它需要很长时间。

4

3 回答 3

4

为了完全放弃搜索字符串上方的内容,我不会使用 File.ReadAllLines,因为它会将整个文件加载到内存中。尝试 File.Open 并将其包装在 StreamReader 中。在 StreamReader.ReadLine 上循环,然后开始写入新的 StreamWriter,或者对底层文件流进行字节复制。

下面列出了如何单独使用 StreamWriter/StreamReader 的示例。

//load the input file
//open with read and sharing
using (FileStream fsInput = new FileStream("input.txt", 
    FileMode.Open, FileAccess.Read, FileShare.Read)) 
{
    //use streamreader to search for start
    var srInput = new StreamReader(fsInput);
    string searchString = "two";
    string cSearch = null;
    bool found = false;
    while ((cSearch = srInput.ReadLine()) != null)
    {
        if (cSearch.StartsWith(searchString, StringComparison.CurrentCultureIgnoreCase)
        {
            found = true;
            break;
        }
    }
    if (!found)
        throw new Exception("Searched string not found.");

    //we have the data, write to a new file
    using (StreamWriter sw = new StreamWriter(
        new FileStream("out.txt", FileMode.OpenOrCreate, //create or overwrite
            FileAccess.Write, FileShare.None))) // write only, no sharing
    {
        //write the line that we found in the search
        sw.WriteLine(cSearch);

        string cline = null;
        while ((cline = srInput.ReadLine()) != null)
            sw.WriteLine(cline);
    }
}

//both files are closed and complete
于 2012-10-04T19:21:19.870 回答
3

您可以使用 LINQ2XML 进行复制

XElement doc=XElement.Load("yourXML.xml");
XDocument newDoc=new XDocument();

foreach(XElement elm in doc.DescendantsAndSelf("etc123"))
{
newDoc.Add(elm);
}

newDoc.Save("yourOutputXML.xml");
于 2012-10-04T19:20:36.830 回答
0

你可以一次做一行......如果检查每一行的内容,则不会使用 read 来结束。

FileInfo file = new FileInfo("MyHugeXML.xml");
FileInfo outFile = new FileInfo("ResultFile.xml");

using(FileStream write = outFile.Create())
using(StreamReader sr = file.OpenRead())
{
    bool foundit = false;
    string line;
    while((line = sr.ReadLine()) != null)
    {
        if(foundit)
        {
            write.WriteLine(line);
        }
        else if (line.Contains("<etc123"))
        {
            foundit = true;
        }
    }
}

请注意,根据您的要求,此方法可能无法生成有效的 XML。

于 2012-10-04T19:27:31.617 回答