コピー前にファイルの完了を確認する
FileSystemWatcher を使用してディレクトリ内のファイルの作成を検出し、その後それらをコピーするシナリオ別の場所に移動する場合、大きなファイル (10MB 以上) が含まれる場合に問題が発生します。ファイルの作成が完了する前にコピー プロセスが開始されたために、「別のプロセスで使用されているため、ファイルをコピーできません」というエラーが発生する可能性があります。
回避策:
唯一知られている回避策は、コピー操作を開始する前にファイルがロックされているかどうかを確認することです。これは、ファイルがロックされていないことを示す false が返されるまで、ファイルが使用中かどうかを繰り返しチェックする関数によって実現できます。
方法 1 (直接コピー):
private bool IsFileLocked(FileInfo file) { FileStream stream = null; try { stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException) { // File still being written, processed, or doesn't exist return true; } finally { if (stream != null) stream.Close(); } // File not locked return false; }
方法 2:
const int ERROR_SHARING_VIOLATION = 32; const int ERROR_LOCK_VIOLATION = 33; private bool IsFileLocked(string file) { // Check destination file status if (File.Exists(file)) { FileStream stream = null; try { stream = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (Exception ex2) { int errorCode = Marshal.GetHRForException(ex2) & ((1 << 16) - 1); if ((ex2 is IOException) && (errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION)) { return true; } } finally { if (stream != null) stream.Close(); } } return false; }
以上が「ファイル使用中」エラーを防ぐために、コピー前にファイルが完了していることを確認する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。