2015-03-13 82 views
0

我有一些使用commons-io FileUtils.openOutputStream(File)方法的新代碼,用於在調用點不存在的文件。這是與「FileNotFoundException」失敗。我第一次以爲這是commons-io中的一個bug,但後來我意識到它只是調用「new FileOutputStream(file,append)」,如果文件不存在,它也會創建該文件。Java 7無法在Win7上用230個字符的路徑創建文件

我加入的代碼我喜歡下面的調用FileUtils.openOutputStream(文件)的前面:

  if (!file.exists()) { 
      logger.info("Parent file exists: " + file.getParentFile().exists()); 
      try { 
       file.createNewFile(); 
      } 
      catch (Exception ex) { 
       logger.error("Creating file failed", ex); 
      } 
     } 

這將打印的父文件「真」,然後「產生java.io.IOException:本系統找不到指定的路徑「。我搜索了這種情況,並且有些人如果超過了Windows上文件路徑的260個字符限制,就會觸發此操作。我認爲這可能是相關的,但我的文件路徑只有230個字符長。

我也嘗試過嘗試在我的Cygwin bash shell中「觸摸」相同的文件路徑,這樣做並不麻煩。

更新

所以我注意到嘗試使用路徑&文件的部分建議做,而不是僅僅「文件」這一點。我的傳入參數是一個「文件」,所以我無法做任何事情。我添加了下面的代碼:

 try { 
      Path path = Paths.get(file.getAbsolutePath()).toAbsolutePath(); 
      if (!Files.exists(path.getParent())) { 
       Files.createDirectories(path); 
      } 
      file = Files.createFile(path).toFile(); 
     } 
     catch (Exception ex) { 
      logger.error("Failed to create file"); 
     } 

有什麼好奇的是,這並沒有給我一個更好的錯誤信息。事實上,它不會給我任何錯誤信息,因爲它不會失敗。看起來NIO正在採用一種非常不同的路徑來創建文件,而不是普通的File對象。

更新

什麼現在是工作的罰款如下:

 file = Paths.get(file.getAbsolutePath()).toAbsolutePath().toFile(); 
     try { 
      Path path = file.toPath(); 
      if (!Files.exists(path.getParent())) { 
       Files.createDirectories(path); 
      } 
      if (!file.exists()) { 
       file = Files.createFile(path).toFile(); 
      } 
     } 
     catch (Exception ex) { 
      logger.error("Failed to create file"); 
     } 

有什麼奇怪的是,我應該能夠除去第一線,基本上是將一個相對路徑絕對路徑。我的測試運行過程中創建了50個左右的文件。我嘗試註釋掉該行,然後清除我的輸出樹並運行測試。它得到以下例外嘗試創建第一個文件:

java.nio.file.AccessDeniedException: build\gen1\org\opendaylight\yang\gen\v1\urn\opendaylight\params\xml\ns\yang\pcep\types\rev131005\vs\tlv\vs\tlv\VendorPayload.java 
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:83) 

什麼?另外請注意,我從來沒有刪除使用「File.createNewFile()」的舊代碼,我只是把「文件」代碼放在那之前,舊代碼檢查「!file.exists()」,所以理論上舊代碼只有在新代碼不會創建文件時纔會執行。在第一個文件上,由於NIO創建失敗,文件仍然不存在,並且它經歷了舊的創建代碼,該創建代碼爲SUCCEEDED。

甚至陌生人,我讓測試用例運行到下一個文件,並未能在新代碼:

java.nio.file.FileAlreadyExistsException: build\gen1\org\opendaylight\yang\gen\v1\urn\opendaylight\params\xml\ns\yang\pcep\types\rev131005\vs\tlv\VsTlv.java 

需要注意的是該塊可能已經得到了這個異常的唯一途徑是,如果它執行「Files.createFile(path).toFile()」這一行,並且它可能已經到達該行的唯一方式是如果「!file.exists()」爲TRUE,這意味着該文件不存在。我的大腦開始融化。還要注意,當我坐在這個斷點處時,我檢查了文件系統,並且該文件不存在。

+0

你介意分享完整的字符串嗎? – selbie 2015-03-13 18:44:18

+0

這是「build/gen1/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/network/topology/unix/rev131222/network/topology/topology/node/path/computation /客戶機/報告/ LSP/LSP /的TLV/VS/TLV /供應商/有效載荷/ UNIX/UnixSubTlvs.java」。 – 2015-03-13 19:56:17

+0

哦。我只是想到了一些事情。這是一個相對路徑。實際的絕對路徑可能超過260個字符。 – 2015-03-13 19:56:59

回答

2

這是2015年,你說你使用Java 7

Don't use File。使用這個來代替:

final Path path = Paths.get("....").toAbsolutePath(); 

// use Files.exists(path.getParent()) to check for the existence; 
// if it doesn't exist use Files.createDirectories() on it 
Files.createFile(thePath); 

如果操作失敗,你至少會得到一個有意義的異常告訴你失敗的原因。

This is 2015. Drop。 File。現在。

+0

好吧,在這一點上完全刪除「文件」是不可能的,但是看看Paths/Files給我什麼是有用的,但是我的結果增加了更多的混淆。我正在添加更新。 – 2015-03-13 19:58:44

+0

沒有錯誤?呵呵。現在這很奇怪。請注意,您可以在'File'上使用'.toPath()'來創建'Path'。不是說我認爲結果會有所不同,但是你也可以嘗試一下嗎? – fge 2015-03-13 20:11:08

+0

我得到奇怪的行爲,如果我不先把文件轉換爲像我在更新中那樣的絕對路徑。我會添加更多信息。 – 2015-03-13 21:17:06