10


1

ファイルは別のプロセスで使用されています

私は大体これを行うプログラムを持っています:

  1. 読み込むファイルを開きます。

  2. ファイルを閉じます

  3. ファイルウォッチャーを起動して、ファイルの変更を監視します。

  4. 変更が検出されるとすぐに、filewatcherのEnableRaisingEvents フラグはfalseに設定され、プロセスはステップ1から繰り返されます。

問題は、ステップ4からステップ1に進んだ後、別のプロセスで使用されていることを示すファイルを読み取れないことです。

受け取ったエラー:

未処理の例外:System.IO.IOException:別のプロセスによって使用されているため、プロセスはファイル 'c:\ test.xml’にアクセスできません。

いただきました! 私のプログラムのステップ1の読者はまだファイルを開いていますか、またはまったく異なるプロセスがファイルにアクセスしていますか?フラグをfalseに設定しても4からステップ1に移動した後、filewatcherはまだファイルを見ていますか?

7 Answer


8


コードがこれに似ている場合:

[STAThread]
static void Main(string[] args)
{
    string file = "temp.txt";
    ReadFile(file);
    FileSystemWatcher fswatcher = new FileSystemWatcher(".\\");
    fswatcher.Changed += delegate(object sender, FileSystemEventArgs e)
                             {
                                 ReadFile(e.FullPath);
                             };
    while (true)
    {
        fswatcher.WaitForChanged(WatcherChangeTypes.Changed);
    }
}
private static void ReadFile(string file)
{
    Stream stream = File.OpenRead(file);
    StreamReader streamReader = new StreamReader(stream);
    string str = streamReader.ReadToEnd();
    MessageBox.Show(str);
    streamReader.Close();
    stream.Close();
}

メモ帳でファイルを編集している場合、[保存]ボタンをクリックすると、ファイルが開いたままになりますが、プログラムを閉じて[保存]をクリックしたときとは異なります。 これがバグであるか、メモ帳の文書化されていない機能であるかはわかりませんが、これは単にあなたの問題かもしれません。 これを修正する1つの方法は、以下を実行することです。

匿名デリゲートで、または `ReadFile()`の呼び出しを実行する場所で、 `Thread.Sleep(1000)`を呼び出して、ファイルを読み取る前にプログラムを待機させ、コードが正常に機能するようにします。


4


http://www.sysinternals.comのProcess Explorerなどのツールを使用して、プロセスのオープンハンドルを持っている人を確認できます。

ほとんどの場合、変更通知を最初に発生させたファイルによって、ファイルは開いたままになります。


3


注:「file.txt」がメモ帳で開いていても、読み取り用に開いているため、このコードは機能します。

using System;
using System.IO;

class Program
{
  static void Main(string[] args)
  {
    ReadFromFile(@"C:\file.txt");
    Console.ReadLine();
  }

  static void ReadFromFile(string filename)
  {
    string line;
    using (StreamReader sr = File.OpenText(filename))
    {
      line  = sr.ReadLine();
      while (line != null)
      {
        Console.WriteLine(str);
        line = sr.ReadLine();
      }
      sr.Close();
    }
  }
}

'' '' '

あるいは単に:

string text = System.IO.File.ReadAllText(@" C:\ file.txt ");


3


他の答えに加えて、「FileWatcher」がファイルに反応するとき、そのアプリによってまだ閉じられていない可能性があります。 ステップ1では、すぐに失敗しないようにしますが、少し遅れていくつかの試行を試みます。


1


問題は、ファイルが作成されたときにFileSystemWatcherがすぐに通知することです。 ファイルが解放されるのを待ちません。 たとえば、コピーに3秒かかる大きなファイルをコピーする場合、その後ファイルを開く必要があります。


0


進行中の可能性のあることがいくつかあります。

最初に、 `IDisposable`を実装するすべての要素を囲むusing句を使用して、ファイルライターを適切に破棄する(閉じるだけでは十分でない)ことを確認します。

次に、単に読んでいるだけで、ファイルを開くときに正しいフラグが設定されていることを確認します。

さらに進むには、これを達成する方法を示すコードブロックを提供すると役立ちます。特にファイルの読み取りについて


0


このMSユーティリティhttp://technet.microsoft.com/en-us/library/cc732490(WS.10).aspx[openfiles]を使用して、開いているファイルのリストを取得し、誰がファイルを開いたかを理解できます。

openfiles /query

また、ネットワークユーザーが開いたファイルを切断することもできます。

openfiles /disconnect /id XXXX

ローカルPCで使用する場合は、オブジェクトリストのメンテナンスグローバルフラグを設定する必要があります。

openfiles /local on

詳細については、http://technet.microsoft.com/en-us/library/cc732490(WS.10).aspx [link]をご覧ください。