2009-05-18 8 views
3

XMLファイル(old.xml)を開き、無効な文字をフィルターに掛け、別のXMLファイル(abc.xml)に書き込むコードです。最後にXML(abc.xml)を再度ロードします。 followlingラインを実行すると、例外がありxmlファイルが別のプロセスによって使用されていると言い、私のコードでどこがリークですか?

xDoc.Load("C:\\abc.xml"); 

は、誰もが何が間違っている任意のアイデアを持っていますか?私のコードに漏れがあり、なぜ(私は常に「キーワード」を使用していますが、漏れを見るのが混乱しています...)?

私のコード全体は、Windows Vista x64でC#+ VSTS 2008を使用しています。

// Create an instance of StreamReader to read from a file. 
    // The using statement also closes the StreamReader. 
    Encoding encoding = Encoding.GetEncoding("utf-8", new EncoderReplacementFallback(String.Empty), new DecoderReplacementFallback(String.Empty)); 
    using (TextWriter writer = new StreamWriter(new FileStream("C:\\abc.xml", FileMode.Create), Encoding.UTF8)) 
    { 
     using (StreamReader sr = new StreamReader(
      "C:\\old.xml", 
      encoding 
      )) 
     { 
      int bufferSize = 10 * 1024 * 1024; //could be anything 
      char[] buffer = new char[bufferSize]; 
      // Read from the file until the end of the file is reached. 
      int actualsize = sr.Read(buffer, 0, bufferSize); 
      writer.Write(buffer, 0, actualsize); 
      while (actualsize > 0) 
      { 
       actualsize = sr.Read(buffer, 0, bufferSize); 
       writer.Write(buffer, 0, actualsize); 
      } 
     } 
    } 

    try 
    { 
     XmlDocument xDoc = new XmlDocument(); 
     xDoc.Load("C:\\abc.xml"); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 

EDIT1:バッファサイズを10Mから1Mに変更しようとしましたが、動作します。私はとても混乱しています、どんなアイデアですか?

EDIT2:入力した古いXMLファイルが100Mなどの非常に大きい場合、この問題は再現が非常に簡単です。私はそれが.NETの既知のバグかどうか疑問に思っています。 ProcessExplorer/ProcessMonitorのようなツールを使用して、どのプロセスがXmlDocument.Loadによってアクセスされないようにファイルをロックするかを確認します。

+0

なぜこのような大きなバッファーですか? (それは問題に関係してはいけませんが、10Mbの理由を知ることは興味深いでしょう...)。私はおそらく10kを使用するかもしれません... –

+0

私は10Mから1Mにバッファのサイズを変更しようとしているし、それは動作します!私はとても混乱しています、どんなアイデアですか? – George2

+0

私はオリジナルのコードで大きなバッファサイズを使用するのは、純粋にテスト目的のためであり、意図的に設定されていない特別な値です。 – George2

答えて

1

あなたのバッファは割り当て解除されていませんか?

+0

私はCLRがすべてのメモリバッファを管理すると思います。混乱している。とにかく、あなたの提案された修正は何ですか?コードを表示してください。 – George2

+0

バッファの割り当てを解除する必要はありません(実際にはメカニズムはありません)。 GCはまもなくそれを手に入れるでしょう(GEN0でおそらく非常に安いでしょう)。 –

+0

ちょうどポイント、バッファはスタックのために大きいので、大きなオブジェクトのヒープに詰め込まれます。つまり、プロセスが実行されている限り、決してコンパクトではありません。 –

1

コードは正常に動作します。ちょうどチェックした。

+0

奇妙な、さらに確認するための任意のアイデア? – George2

+0

いいえ...あなたのワークステーションに問題があると思います。コードが機能するので、クリスタルボールだけがあなたを助けてくれます。 –

4

それは私のためにうまく動作します。 純粋に推測ですが、おそらくウィルスチェッカーがファイルをスキャンしていますか? 調査するには、ウイルスチェッカーを無効にし、正常に機能するかどうかを確認してから、ウイルスチェッカーを再度有効にしてください。

脇に、ある方法がありますファイルを開いたままにします。StreamReaderコンストラクタが例外をスローした場合。しかし、その後、あなたはとにかくXmlDocumentものに達する...しかし、考慮されません:今

using (FileStream fs = new FileStream("C:\\abc.xml", FileMode.Create)) 
using (TextWriter writer = new StreamWriter(fs, Encoding.UTF8)) 
{ 
    ... 
} 

fsnew StreamWriter(...)はスローエッジケース内に配置されています。しかし、私はではありません。は、これが問題であると考えています。

+0

私はバッファのサイズを10Mから1Mに変更しようとしました。私はとても混乱しています、どんなアイデアですか? – George2

1

を使用すると、Disposeが呼び出されますが、Disposeは書き込みストリームで閉じるコールですか?そうでない場合でも、システムはファイルを書き込み用に開いていると見なすことがあります。

私はusingブロックの直前にwriterを閉じてみます。

編集:ちょうど自分自身でコードを試しました。あなたが見ている問題なしにコンパイルして実行しました。ウイルススキャナーをオフにして、他の人が触れたようにして、ファイルを開いたままの場所にウィンドウがないことを確認してください。

+1

Close()はDispose()の呼び出しによって実装され、StreamReaderまたはStreamWriterを閉じると、元のストリームも閉じます。だから、これは助けにならないでしょう。 –

1

他のプロセスがファイルにアクセスしようとしていないことを確認しましたか?

+0

私はバッファのサイズを10Mから1Mに変更しようとしました。私はとても混乱しています、どんなアイデアですか? – George2

2

おそらく、ルート上でFileSystemWatcherを実行していますか?

ProcessMonitorを使用して、そのファイルにアクセスしたユーザーを確認することもできます。

+0

FileSystemWatcher?どういう意味ですか? – George2

+0

FileSystemWatcherクラス。 – leppie

+0

いいえ、私はそのクラスを明示的に使用していません。すべてのコードを投稿しました。私はバッファのサイズを10Mから1Mに変更しようとしました。私はとても混乱しています、どんなアイデアですか? – George2

2

問題は大きいと思われるchar[]です。それが大きすぎる場合、スタック上ではなく大きなオブジェクトヒープ上に配置されます。したがって、大きなオブジェクトヒープは、ソフトウェアが実行されている間は圧縮されません。一度割り当てられたスペースは再び使用されないかもしれません。これはメモリリークのように見えます。配列を小さな塊に分割してみてください。

+1

私は、バッファが大型であることを認めますが、問題文 "例外があるとxmlファイルは別のプロセスで使用されています"と何が関係していますか?バッファー –

+0

小さなバッファーサイズを使用すると試しましたが、私のコードは問題なく動作します。特大のバッファがファイルを閉じられないようにするのはなぜですか?私が最初に会ったエラーはファイルが閉じていないと思いますか? – George2

+1

この場合、+1からBeowulfOF;オーバーサイズされたバッファがこれを引き起こすことは明らかではないようです(実際には、私はローカルに問題はありません)...好奇心が強いです。 OutOfMemoryException、確かに...ファイルロック?非常に奇妙な... –

1

それは一部の人ではなく、他の人には当てはまらないという事実は、ファイルがクローズされていないと私に思います。ファイルをロードする前にライターを閉じます。

+1

ファイルが閉じられていない場合は、誰にでも動作しません!コードは、ファイルが閉じていることを示しています(このスレッド/プロセスの範囲内で少なくとも) –

2

私は、誰がファイルをロックしているのかを見るために、ProcessMonitor(または同等のもの)を使用して2番目のLeppieの提案をしました。それ以外はただの推測です。

1

私はあなたがいくつかのウイルス対策ソリューションを実行していて、ファイルを閉じた後にロックすることを考えています。確認するには、ファイルをロードする前に遅延(1秒など)を追加してみてください。それがうまくいくなら、おそらく原因が分かりました。

0

実行Process Explorer

それが最初のファイルをロックし、あなたのプログラムのことを確認してください。

関連する問題