文件鎖定
文件鎖定初看起來可能讓人迷惑。它似乎指的是防止程序或者用戶訪問特定文件。事實上,文件鎖就像常規(guī)的 Java 對象鎖 ― 它們是勸告式的(advisory)鎖。它們不阻止任何形式的數(shù)據(jù)訪問,相反,它們通過鎖的共享和獲取賴允許系統(tǒng)的不同部分相互協(xié)調。
可以鎖定整個文件或者文件的一部分。如果獲取一個排它鎖,那么其他人就不能獲得同一個文件或者文件的一部分的鎖。如果獲得一個共享鎖,那么其他人可以獲得同一個文件或者文件一部分的共享鎖,但是不能獲得排它鎖。文件鎖定并不總是出于保護數(shù)據(jù)的目的。例如,可能臨時鎖定一個文件以保證特定的寫操作成為原子的,而不會有其他程序的干擾。
大多數(shù)操作系統(tǒng)提供了文件系統(tǒng)鎖,但是它們并不都是采用同樣的方式。有些實現(xiàn)提供了共享鎖,而另一些僅提供了排它鎖。事實上,有些實現(xiàn)使得文件的鎖定部分不可訪問,盡管大多數(shù)實現(xiàn)不是這樣的。
鎖定文件
要獲取文件的一部分的鎖,您要調用一個打開的 FileChannel 上的 lock() 方法。注意,如果要獲取一個排它鎖,您必須以寫方式打開文件。
RandomAccessFile raf = new RandomAccessFile( "usefilelocks.txt", "rw" );
FileChannel fc = raf.getChannel();
FileLock lock = fc.lock( start, end, false );
在擁有鎖之后,您可以執(zhí)行需要的任何敏感操作,然后再釋放鎖:
lock.release();
在釋放鎖后,嘗試獲得鎖的其他任何程序都有機會獲得它。
文件鎖定和可移植性
文件鎖定可能是一個復雜的操作,特別是考慮到不同的操作系統(tǒng)是以不同的方式實現(xiàn)鎖這一事實。下面的指導原則將幫助盡可能保持代碼的可移植性:
- 只使用排它鎖。
- 將所有的鎖視為勸告式的(advisory)。
public class NIOFileLockTest {
private final int start = 10;
private final int end = 20;
@Test
public void fileLockTest() {
try {
RandomAccessFile raf = new RandomAccessFile(
"/Users/dongsj/workspace/dsj/javaSpace/nettyDemo/src/test/resources/nio/readandshow.log",
"rw");
FileChannel fc = raf.getChannel();
System.out.println("獲取鎖");
FileLock lock = fc.lock(start, end, false);
System.out.println("獲取鎖成功");
System.out.println("暫停3s");
Thread.sleep(3000);
System.out.println("釋放鎖");
lock.release();
System.out.println("釋放鎖成功");
raf.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}