![](/img/trans.png)
[英]solaris 10, java 6 , file.exists cant see the existing file
[英]Java File.exists and other File operations returning wrong results for an existing File (network, macosx)
從頭開始安裝文件系統AirportHDD(AFP),並且當我啟動此小程序時文件存在。 我試圖整天弄清楚以下原因為何不起作用,但找不到任何解決方案:
public static void main(String[] arguments)
{
while(1==1)
{
File f=new File(
"/Volumes/AirportHDD/test/lock.csv");
System.out.println(f.exists());
AmySystem.sleep(100);
}
}
輸出為:true,true,...
一旦我從另一台計算機上刪除了文件(AirportHDD是通過網絡安裝的硬盤),輸出就會一直說:true,true,...當我打開finder並轉到該目錄時,輸出更改為:false,false ,...
當再次添加文件(通過另一台PC)時,輸出仍然是:false,false,...
但是,如果再次打開查找程序並單擊目錄,查找程序會顯示現有文件,則輸出突然變為:false,true,true,true,...。
注意:
只要java“認為”文件不存在,所有其他文件操作(如打開讀取)都會失敗
如果程序本身正在創建和刪除文件,則不會發生問題
剛剛在測試時發現,使用samba共享所有內容都可以,但是使用AFP則無法使用
有沒有辦法告訴Java做與finder一樣的事情,例如刷新,或者不嘗試緩存,無論如何?
我認為您可能正在尋找WatchService 。 Oracle也很友善地提供了教程 。
因為不能保證這些鏈接的壽命,所以我將在幾分鍾內編輯示例代碼。 我只是想讓您知道,我想我發現了一些東西,以防您想自己動手看。
更新在鏈接的教程之后,我想到了這樣的代碼。 我不確定它是否可以工作(沒有時間對其進行測試),但這可能足以使您入門。 WatchService
還具有一個take()
方法,該方法將等待事件,這意味着您可以根據您給出的最后一個輸出來假設文件的存在(或不存在)。 這實際上取決於該程序將與之交互的對象。
如果可行,那就很好。 如果沒有,也許我們可以根據遇到的任何錯誤找出解決方法。 或者,如果其他人比我更熟悉此代碼,則其他人可能會提出並提供此代碼的更好版本(或完全提供更好的選擇)。
public static void main(String[] arguments) {
Path path = Paths.get("/Volumes/AirportHDD/test/lock.csv");
WatchService watcher = FileSystems.getDefault().newWatchService();
WatchKey key = null;
try {
key = path.register(watcher,
ENTRY_CREATE,
ENTRY_DELETE);
} catch (IOException x) {
System.err.println(x);
}
while(true) {//I tend to favor this infinite loop, but that's just preference.
key = watcher.poll();
if(key != null) {
for (WatchEvent<?> event: key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
if (kind == OVERFLOW || kind == ENTRY_DELETE) {
System.out.println(false);
}
else if (kind == ENTRY_CREATE) {
System.out.println(true);
}
}//for(all events)
}//if(file event occured)
else {
File f=new File(path);
System.out.println(f.exists());
}//else(no file event occured)
AmySystem.sleep(100);
}//while(true)
}//main() method
這是一個顯示問題的JUnit測試。在OSX Mavericks上使用Samba仍然會發生問題。 該聲明解釋了一個可能的原因: http ://appleinsider.com/articles/13/06/11/apple-shifts-from-afp-file-sharing-to-smb2-in-os-x-109- 小牛
它積極地緩存文件和文件夾屬性,並使用機會鎖定來更好地緩存數據。
請在下面找到一個checkFile,該文件實際上將嘗試讀取幾個字節並強制進行真正的文件訪問,以避免緩存異常。
JUnit測試:
/**
* test file exists function on Network drive
* @throws Exception
*/
@Test
public void testFileExistsOnNetworkDrive() throws Exception {
String testFileName="/Volumes/bitplan/tmp/testFileExists.txt";
File testFile=new File(testFileName);
testFile.delete();
for (int i=0;i<10;i++) {
Thread.sleep(50);
System.out.println(""+i+":"+OCRJob.checkExists(testFile));
switch (i) {
case 3:
// FileUtils.writeStringToFile(testFile, "here we go");
Runtime.getRuntime().exec("/usr/bin/ssh phobos /usr/bin/touch "+testFileName);
break;
}
}
}
checkExists源代碼:
/**
* check if the given file exists
* @param f
* @return true if file exists
*/
public static boolean checkExists(File f) {
try {
byte[] buffer = new byte[4];
InputStream is = new FileInputStream(f);
if (is.read(buffer) != buffer.length) {
// do something
}
is.close();
return true;
} catch (java.io.IOException fnfe) {
}
return false;
}
問題是網絡文件系統AFP。 通過使用SAMBA,一切都可以按預期進行。
在這些情況下,也許OS使用AFP在OSX中返回了錯誤的文件信息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.