我想測試以查看是否可以鎖定文件X.如果文件不存在或無法鎖定,則失敗。這聽起來很簡單,但我一直陷入死衚衕。答案的一個捷徑是提供一種方法來獲得一個FileChannel,我可以獨佔鎖,而沒有任何創建文件的風險。讓我解釋一下......如何鎖定文件,如果存在,請不要創建它?
我不能使用NIO lock()
而沒有可寫的FileChannel,而且我不能在不打開文件X的情況下獲得可寫的FileChannel,如果它不存在,就會創建它。我找到的每個Java方法都試圖打開文件X爲可寫,如果它不存在,並且似乎沒有辦法在只讀文件通道上專門鎖定文件,就會創建它。
即使首先檢查確認文件是否存在也是有問題的。這裏是我的最新代碼:
private LockStatus openAndLockFile(File file) {
if (Files.notExists(file.toPath())) {
synchronized (fileList) {
removeFile(file);
}
return LockStatus.FILE_NOT_FOUND;
}
try {
rwFile = new RandomAccessFile(file, "rw");
fileLock = rwFile.getChannel().lock();
}
catch ...
這段代碼的問題是NotExists
代碼運行時該文件可能存在,但由new RandomAccessFile(file, "rw")
運行的時間消失。這是因爲我在多個線程和多個進程中運行此代碼,這意味着代碼必須密封並且堅如磐石。
下面是在兩個過程運行與我的現有代碼的問題的一個例子:
1:方法A檢測到新文件
2:方法B檢測到相同的文件
3:處理A處理文件並將其移動到另一個文件夾
問題--->處理B意外地創建一個空文件。 OOPS!
4:進程B檢測到進程B創建的新文件,並處理它創建一個0字節的重複文件。
5:進程A也檢測不小心被進程B創建新的文件,並試圖對其進行處理......
下面是使用的什麼我C#示例試圖做到:
Stream iStream = File.Open("c:\\software\\code.txt", FileMode.Open,
FileAccess.Read, FileShare.None)
任何幫助或提示,非常感謝!謝謝!
圍繞關鍵塊同步 – MadProgrammer
感謝您的建議。當代碼在完全獨立的進程中運行時,這是如何工作的?可能在不同的機器上? –
那麼顯然使用文件是錯誤的方法,除非文件系統在這些機器之間共享。這可能會更好:http://stackoverflow.com/questions/1059580/distributed-lock-service –