XMLファイルをコンパイルするために長期間実行されるREST APIメソッドがあります。ユーザーはこのコンパイルを開始する要求を行い、基本ファイルが作成され、ユーザーに進行状況を照会するための一意のIDが与えられます。XMLファイルを書き込んでいるときに読む
progress-readingメソッドは、読み取り専用アクセスでファイルを開き、XDocument
オブジェクトをインスタンス化し、その中の要素の数を数えます。
を XMLファイルは
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read))
{
var xmlDoc = XDocument.Load(fs);
foreach (...)
{
// add the element to xmlDoc
xmlDoc.Save(filePath);
}
}
そしてをファイルに、しかし要素
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var xmlDoc = XDocument.Load(fs);
// count elements
}
の数をカウントするためにを読み取るコードでアクセスされ移入コードにはメソッドがあり、例外がスローされますxmlDoc.Save(filePath);
プロセスは、別のプロセスによって使用されているため、ファイル '...'にアクセスできません。
私はそれを理解できるように、FileShare.Read
でのFileStreamを開くと、別のプロセスが読み取り専用アクセスでファイルを開くことができます(と私はこれが起こっていると考えている)と同様に読み取り/カウント方法でFileShare.ReadWrite
を使用して移入を可能にします書き込みアクセスでファイルを開くプロセス。
上記のコードでは、どちらのプロセスでも私が期待することができないのはなぜですか?
"古いコンテンツを切り捨てるために保存する前にストリームの長さをゼロに設定することもできます"という提案の理由を説明できますか?ストリームの内容を保存する前にストリームを_length_に0に設定しないでください。または、あなたは現在の位置に長さを設定する必要があると書いていたのでしょうか? – awj
まず、既存のコンテンツを含むストリームを開き、その内容をXDocument(XDocument.Load)に読み込みます。ファイルが1000バイトであったとします。保存する前に、ストリームの長さは1000で、位置は1000です.0の位置を決めて保存します。ここで、新しい文書の長さが900であるとします。XDocument.Saveがストリームの長さ自体を900に設定しないと、新しい文書が900バイト、前の文書が100バイト、合計で1000になります。欲しいです。私はXDocument.Saveが内部的にどのように動作するのか分からないので、私は、保存する前にストリームを切り捨てて、確かめることを提案しました。 – Evk
OK、作成する2点:(1)ファイルに書き込まれる内容は増加するだけです。開いたとき、FileStreamは決してそれよりも短くなることはありません。 (2)これを実装している間に、「ストリームの開始前に位置を移動しようとしました」という例外が発生しています。これは一見無作為な時に起こります - 時には最初のクエリ読み込みの間に、他の時はずっと後に起こります。 – awj