Java基礎--FileDescriptor sync方法
在讀Lucene的原始碼過程中,發現FSDirectory類中有一個檔案資訊同步的方法,對其中的一行程式碼file.getFD().sync();不是很清楚(這也可見自己的基礎有多麼的差)。經過一番檢索,終於明白了其大意。
protected void fsync(String name) throws IOException {
File fullFile = new File(directory, name);
boolean success = false;
int retryCount = 0;
IOException exc = null;
while (!success && retryCount < 5) {
retryCount++;
RandomAccessFile file = null;
try {
try {
file = new RandomAccessFile(fullFile, "rw");
file.getFD().sync();//強制所有系統緩衝區與基礎裝置同步
success = true;
} finally {
if (file != null)
file.close();
}
} catch (IOException ioe) {
if (exc == null)
exc = ioe;
try {
// Pause 5 msec
Thread.sleep(5);
} catch (InterruptedException ie) {
throw new ThreadInterruptedException(ie);
}
}
}
if (!success)
// Throw original exception
throw exc;
}
}
File fullFile = new File(directory, name);
boolean success = false;
int retryCount = 0;
IOException exc = null;
while (!success && retryCount < 5) {
retryCount++;
RandomAccessFile file = null;
try {
try {
file = new RandomAccessFile(fullFile, "rw");
file.getFD().sync();//強制所有系統緩衝區與基礎裝置同步
success = true;
} finally {
if (file != null)
file.close();
}
} catch (IOException ioe) {
if (exc == null)
exc = ioe;
try {
// Pause 5 msec
Thread.sleep(5);
} catch (InterruptedException ie) {
throw new ThreadInterruptedException(ie);
}
}
}
if (!success)
// Throw original exception
throw exc;
}
}
FileDescriptor檔案描述符類的例項用作與基礎機器有關的某種結構的不透明控制程式碼,該結構表示開放檔案、開放套接字或者位元組的另一個源或接收者。檔案描述符的主要實際用途是建立一個包含該結構的 FileInputStream 或 FileOutputStream。 應用程式不應建立自己的檔案描述符。
大部分人都認為flush後,其他使用者應該立即可見。但是在一些極端的情況下也需呼叫後還是無法看見以寫入的資料。
flush
重新整理此輸出流並強制寫出所有緩衝的輸出位元組。flush 的常規協定是:如果此輸出流的實現已經緩衝了以前寫入的任何位元組,則呼叫此方法指示應將這些位元組立即寫入它們預期的目標。
如果此流的預期目標是由基礎作業系統提供的一個抽象(如一個檔案),則重新整理此流只能保證將以前寫入到流的位元組傳遞給作業系統進行寫入,但不保證能將這些位元組實際寫入到物理裝置(如磁碟驅動器)。
OutputStream 的 flush 方法不執行任何操作。為什麼會這樣? 原因是,這個緩衝我們java自己實現的。 flush保證的是內部的緩衝寫入到系統中。但是系統中檔案也可能有緩衝,所以並不一定flush後立即可見。
那麼如何解決這個問題?在檔案流或資料流中均可以看見getFD()這個方法, 它返回的是與此流有關的檔案描述符。
所以呼叫檔案描述符的sync的方法即可讓實際檔案強制同步了。JDK中描述如下:
sync
強制所有系統緩衝區與基礎裝置同步。該方法在此 FileDescriptor 的所有修改資料和屬性都寫入相關裝置後返回。特別是,如果此 FileDescriptor 引用物理儲存介質,比如檔案系統中的檔案,則一直要等到將與此 FileDesecriptor 有關的緩衝區的所有記憶體中修改副本寫入物理介質中,sync 方法才會返回。 sync 方法由要求物理儲存(比例檔案)處於某種已知狀態下的程式碼使用。例如,提供簡單事務處理設施的類可以使用 sync 來確保某個檔案所有由給定事務造成的更改都記錄在儲存介質上。 sync 隻影響此 FileDescriptor 的緩衝區下游。如果正透過應用程式(例如,透過一個 BufferedOutputStream 物件)實現記憶體緩衝,那麼必須在資料受 sync 影響之前將這些緩衝區重新整理,並轉到 FileDescriptor 中(例如,透過呼叫 OutputStream.flush)。來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28624388/viewspace-763524/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- vue基礎 - syncVue
- 【Java基礎】方法Java
- Java基礎 --- 方法Java
- Java基礎——方法的呼叫Java
- java基礎toString()方法Java
- Java基礎之泛型方法Java泛型
- Java基礎知識七——方法Java
- Java基礎-工廠方法模式Java模式
- java基礎:Object的equals方法JavaObject
- Java基礎系列-equals方法和hashCode方法Java
- java基礎:執行緒方法之yield方法Java執行緒
- java基礎:Object 的toString方法JavaObject
- [Java 基礎]--呼叫webservice介面的方法JavaWeb
- Java基礎知識篇05——方法Java
- Java基礎——ArrayList方法全解(字典版)Java
- java基礎:執行緒方法之joinJava執行緒
- Java基礎-語法基礎Java
- Java基礎02 方法與資料成員Java
- Java基礎-- ==號與equals()方法的區別Java
- Java程式設計基礎05——方法(函式)Java程式設計函式
- 《java程式設計基礎》方法的過載Java程式設計
- JAVA 基礎Java
- 【Java基礎】Java
- java基礎Java
- [Java基礎]Java
- Java基礎-設計一個Java類所需的方法(轉)Java
- Java 基礎02Java程式設計基礎Java程式設計
- java基礎-java NIOJava
- Java基礎-物件導向基礎Java物件
- Java基礎03 構造器與方法過載Java
- 零基礎全方位學習java的方法Java
- Java基礎知識整理之static修飾方法Java
- Java-基礎語法20:Lambda&方法引用Java
- java基礎:執行緒方法之interrupt和sleepJava執行緒
- 【Java基礎】--深入剖析基礎語法Java
- Scanner——Java基礎Java
- Java 反射基礎Java反射
- 【Java基礎】ServletJavaServlet