4

次のXMLファイルがあるとします。

<book>
 <name>sometext</name>
 <name>sometext</name>
 <name>sometext</name>
 <name>Dometext</name>
 <name>sometext</name>
</book> 

ファイル全体を読み書きせずに、Dをsに変更してコンテンツを変更したい場合(4番目の「名前」ノードに示されているように)、これは可能でしょうか?

4

4 に答える 4

3

10MBのファイルは問題ありません。それを丸呑みにする。DOMを変更します。それをファイルシステムに書き戻します。10GBはもっと問題です。その場合:

仮定:ファイルの長さを変更していません。ファイルは、文字の(リンクされた)リストではなく、文字の配列と考えてください。途中に文字を追加することはできず、変更するだけです。

seekファイル内の位置を変更してから、writeその文字をディスクに移動する必要があります。

.NETの世界では、FileStreamオブジェクトを使用して、Position属性を文字のインデックスに設定してからD、単一のs文字を記述します。テキストファイルのランダムアクセスに関するこの質問を確認してください

この質問も読んでください:C#を使用してファイルに文字を挿入する方法。オブジェクトを実際に使用することはできないようですがFileStream、代わりに個々のバイトを書き込む必要があります。

幸運を。しかし、実際には、10 MBしか話していない場合は、それを丸呑みにしてください。コンピューターがあなたの仕事をしているはずです。

于 2011-10-13T08:37:44.993 に答える
2

ファイルを読み込んで処理し、吐き出すだけです。

これは、 XmlReaderを使用してストリーミング方式で実行できます。これは、XmlDocumentまたはXDocumentよりも手作業ですが、メモリ内DOMの作成を回避します(XmlDocument / XDocumentは、これと同じ読み取り/書き込みパターンで使用できますが、通常はメモリ内の完全な再構築):

  1. ファイル入力ファイルストリームを開く(XmlReader)
  2. 出力ファイルストリームを開きます(XmlWriter、別のファイルへ
  3. XmlReaderから読み取り、必要に応じて変換を実行するXmlWriterに書き込みます。
  4. ストリームを閉じる
  5. 新しいファイルを古いファイルに移動します(上書き、アトミックアクション)

これは、同じ開いているファイルで入力と出力を処理するように設定できますが、非常に巧妙な作業がたくさんあり、何も保存されません。ファイルの長さを短くすると、多くのエッジケースが発生します。実際、ファイルの内容を逆方向にシフトしてギャップを埋めたり、ファイルの内容を順方向にシフトして新しいスペースを作成したりするのは、時間がかかる場合がありますファイルシステムキャッシュは、最も基本的な長さを維持する操作以外の場合、「利益」を最小限に抑える/無駄にする可能性があります。さらに、ファイルを適切に変更することはアトミックなアクションではなく、エラーが発生した場合は通常回復できません。一時ファイルを犠牲にして、読み取り/書き込み/移動のアプローチは最終的なファイルの内容に対してアトミックです。

または、XSLTを検討してください-これはこのために設計されました;-)

ハッピーコーディング。

于 2011-10-13T08:40:36.940 に答える
1

最もクリーンな(そして最良の)方法は、XmlDocumentオブジェクトを使用して操作することですが、迅速で汚い解決策は、XMLを文字列に読み込んでから、次のことを行うことです。

xmlText = xmlText.Replace("Dometext", "sometext");
于 2011-10-13T08:23:48.373 に答える
1

XMLファイルはテキストファイルであり、挿入/削除はできません。サポートされているミューテーションは、OverWriteとAppendのみです。XMLには適していません。

したがって、最初に、これが本当に必要であることを確認してください。これは複雑な操作であり、非常に大きなファイルでのみ価値があります。

長さが変わる可能性があるため、少なくとも最初の交換後にすべてを移動する必要があります。複数の置換が可能であるということは、変更に対応するために大きなバッファーが必要になる可能性があることを意味します。

ファイル全体をコピーする方が簡単です。これはI/Oにコストがかかりますが、メモリ使用量を節約できます。

于 2011-10-13T08:39:42.727 に答える