7


1

C#では、FileSystemWatcherオブジェクトを使用して特定のファイルを監視し、ファイルの作成、変更などの際にイベントを発生させることができます。

このクラスで私が抱えている問題は、ファイルを作成したプロセスがまだ書き込み中であっても、ファイルが作成された瞬間にイベントが発生することです。 私はこれが非常に問題であることを発見しました、特に私がファイルがそれへの書き込みが完了するまで存在しないであろうそれに対して何らかの構造を持たなければならないXML文書のような何かを読み込もうとするなら。

4 Answer


5


ファイルシステムウォッチャーを使用して、ファイルがいつ変更されたかを確認できます。 それは以前にファイルを持っていたプログラムがファイルを閉じた後に初めて "変更"になります。 私はあなたがC#を要求したことを知っています、しかし私のVB.Netははるかに良いです。 あなたまたは他の誰かが翻訳できることを願っています。

ファイルが開かれない場合は、ウォッチャーを追加し、ファイルが変更されるのを待ちます。 ファイルが変更された後に、再度開こうとします。 ファイルが解放されないという状況に巻き込まれる可能性があるため、120秒以上待つと例外がスローされます。 また、実際のファイル監視プログラムが作成される前にファイルが閉じられた可能性が小さい場合に備えて、5秒のファイル変更を待つタイムアウトを追加することにしました。

Public Sub WriteToFile(文字列としてのByVal FilePath、文字列としてのByVal FileName、バイトとしてのByVal Data()System.IO.FileStreamとしてのDim File = Nothing DimとしてのStartTime DateTimeとしてのDim MaxWaitSecondsとしての整数= 120

StartTime = DateTime.Now

FileOpen = False

試してくださいFile = New System.IO.FileStream(FilePath

例外としてキャッチ

DateTime.Now.Subtract(StartTime).TotalSeconds> MaxWaitSecondsの場合は、新しい例外をスローします( "Waiting more")

FileWatch = New System.IO.FileSystemWatcher(FilePath、FileName)FileWatch.WaitForChanged(IO.WatcherChangeTypes.Changed、5000)End If

FileOpen = False

試行終了

FileOpenでないときにループ

FileOpenの場合File.Write(Data、0、Data.Length)File.Close()Endの場合End Subの場合


0


標準クラスによって実際に発生するイベントの方法があるかどうかはわかりませんが、最近行った作業で同様の問題が発生する可能性があります。

つまり、その時点でロックされていたファイルに書き込もうとしていました。 書き込みメソッドをラップしたので、数ms後に自動的に書き込みが再試行されます。

大声で考えて、ReadOnlyステータスのファイルを調査できますか? それから、保留中のファイル操作または何かのためにデリゲートを積み重ねることができるファイルIOのためのラッパーを持つ価値があるかもしれません.. 考えですか?


0


http://msdn.microsoft.com/ja-jp/library/aa363858.aspx[CreateFile]をOPEN_EXISTINGフラグとFILE_ALL_ACCESSを指定したループで使用します(またはサブセットのみが必要な場合は、http:// msdnを参照してください)。 microsoft.com/en-us/library/aa364399(VS.85).aspx

失敗した場合に-1(INVALID_HANDLE_VALUE)に対して返されたハンドルを調べます。 それはまだ投票しています、しかしこれは例外投げの費用を節約します。

編集:このエディタ/マークアップはアンダースコアを処理することはできません! バー!


0


Kibbeの答えは正しいようですが私にはうまくいきませんでした。 FileSystemWatcherにはバグがあるようです。 だから私は私自身のWaitForChangedを書きました:

using(var watcher = new FileSystemWatcher(MatlabPath、fileName)){var wait = new EventWaitHandle(false、EventResetMode.AutoReset); watcher.EnableRaisingEvents = true; watcher.Changed = delegate(オブジェクトセンダ、FileSystemEventArgs e){wait.Set(); ; if(!wait.WaitOne(MillissecondsTimeout)){新しいTimeoutException()をスローします。 }}