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

一度に1行ずつ実行できます...各行の内容を確認する場合、読み取りを使用して終了しません。

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 に答える