2013-05-30 51 views
5

我正在嘗試編寫在NFS文件系統上的Linux環境上運行的Java應用程序。在Java中區分ESTALE和ENOENT的最佳方法

我注意到當我打電話給java.io.File.exists()時,它對於ESTALE(陳舊的NFS文件句柄)和ENOENT(沒有這樣的文件或目錄)都返回false。對於我的申請,我需要能夠區分兩者。

目前我正在考慮使用JNA來實現stat()的調用,但這似乎是矯枉過正的,不得不實施整個統計結構和所有依賴平臺的東西。

有沒有簡單的方法來簡單地獲得像File.exists()這樣的Java調用之後的底層errno或任何其他想法來解決這個問題?

回答

2

有了JNA,您實際上不必實施stat結構;你只需要分配足夠大的內存來表示本地結構。您可以撥打Native.getLastError()來檢索errno的值。

Pointer fake_stat = new Memory(2048); // big enough 
if (clib.stat(filename, fake_stat) != 0) { 
    int errno = Native.getLastError(); 
    ... 
} 
+0

我喜歡這個建議。我也考慮過實現'access(file,F_OK)',而這個過程要簡單得多,但實際上並沒有區分'ESTALE'和'ENOENT'。但最終我們找到了一個不需要這種差異化的解決方案。 –

1

如果您的性能要求很低,我只需實現一個小型C程序,該程序針對給定的文件名稱調用stat,並將errno的值輸出到stdout。然後從Java調用它:

#include <stdio.h> 
#include <sys/stat.h> 
#include <errno.h> 

int main(int argc, char * argv[]) { 
    struct stat buf; 
    char const * const fileName = argv[1]; 
    int const ret = stat(fileName, &buf); 
    printf("File %s: Return %d, errno %d\n", fileName, ret, errno); 
    if (errno) { 
    perror("Error"); 
    } 
} 

從命令行,這需要4ms。在你的情況下,如果以前的exists()返回錯誤,你可能只需要調用它。

其他可能性:考慮將它封裝在一個小的TCP服務器中,讓Java使用套接字與它進行通信。或者將它用作apache中的CGI腳本,並讓Java使用HTTP。

如果這仍然太慢,您可能必須採用JNI/JNA方式。