2008-09-25 350 views
11

我嘗試使用下面的代碼複製文件:哪些java.io.IOException的可能原因:「文件名,目錄名或卷標語法不正確」

File targetFile = new File(targetPath + File.separator + filename); 
... 
targetFile.createNewFile(); 
fileInputStream = new FileInputStream(fileToCopy); 
fileOutputStream = new FileOutputStream(targetFile); 
byte[] buffer = new byte[64*1024]; 
int i = 0; 
while((i = fileInputStream.read(buffer)) != -1) { 
    fileOutputStream.write(buffer, 0, i); 
} 

對於一些用戶在targetFile.createNewFile導致此異常:

java.io.IOException: The filename, directory name, or volume label syntax is incorrect 
    at java.io.WinNTFileSystem.createFileExclusively(Native Method) 
    at java.io.File.createNewFile(File.java:850) 

文件名和目錄名似乎是正確的。在執行復制代碼之前的目錄targetPath甚至檢查是否存在以及文件名看起來像這樣:AB_timestamp.xml

用戶有寫權限targetPath,可以複製該文件,而無需使用操作系統的問題。

由於我沒有訪問此機還發生在,不能重現我爲你們的提示在此例外的原因,我自己的機器上的問題。

回答

5

試試這個,因爲它需要在TARGETPATH和文件名之間的路徑調整目錄分隔符的更多的關懷:

File targetFile = new File(targetPath, filename); 
0

你檢查TARGETPATH是一個目錄,或者存在同名只是些什麼呢? (我知道你說用戶可以從操作系統複製它,但也許他們正在輸入其他東西)。

targetPath是否已經以File.separator結束?

(這將有助於如果您可以登錄並告訴我們TARGETPATH和文件名的值是一個失敗的情況下)

0

也許問題是,它是複製在網絡上的文件,在共享驅動器?我認爲在使用NFS編寫文件時,如果路徑是\ mypc \ myshared文件夾,Java可能會出現問題。

這個問題發生的路徑是什麼?

0

嘗試添加一些記錄,看看到底什麼是文件試圖創建,以確保父母是很好的目錄名稱和路徑。

此外,您還可以看看電視,而不是使用循環。 ;-)

0

你說「對於一些用戶」 - 所以它適用於其他人?這裏有什麼區別,用戶是在不同的機器上運行不同的實例,還是服務於併發用戶的服務器?

如果是後者,我會說這是一種併發錯誤莫名其妙 - 兩個線程檢查嘗試創建與WinNTFileSystem.createFileExclusively(本機方法)同時放文件。

當我看在OpenJDK源無論createNewFile或createFileExclusively是同步的,所以你可能要同步這個塊自己。

1

嘗試在不同目錄中創建文件 - 例如, 「C:\」在你確認你有寫入權限之後。如果可行,文件的路徑名稱是錯誤的。

看看在異常的註釋,並嘗試以改變文件的路徑名的所有元素。實驗。得出結論。

0

也許文件已經存在。如果您的時間戳分辨率不夠好,可能會出現這種情況。由於它是一個IOException,因此您可能不會遇到權限問題(在這種情況下,您將得到一個SecurityException)。

在嘗試創建文件並嘗試記錄發生的事情之前,我會首先檢查文件是否存在。

查看public boolean createNewFile()瞭解更多關於您正在使用的方法的信息。

+0

API實際上表示,如果文件已經存在但不會拋出IOException,但在此情況下僅返回false。 – Turismo 2008-09-25 09:51:15

0

由於我無法重現我自己的機器上的錯誤或拿到手的代碼失敗的用戶的機器我一直等到現在宣佈一個被接受的答案。 我改變了代碼如下:

File parentFolder = new File(targetPath); 
... do some checks on parentFolder here ... 
File targetFile = new File(parentFolder, filename); 
targetFile.createNewFile(); 
fileInputStream = new FileInputStream(fileToCopy); 
fileOutputStream = new FileOutputStream(targetFile); 
byte[] buffer = new byte[64*1024]; 
int i = 0; 
while((i = fileInputStream.read(buffer)) != -1) { 
    fileOutputStream.write(buffer, 0, i); 
} 

它的工作對用戶報告問題之後。

所以看起來Alexanders的答案有訣竅 - 儘管我實際上使用的構造函數與他給出的略有不同,但沿着相同的路線。

我還沒有通過再次運行舊版本並檢查它是否仍然失敗來幫助我驗證代碼更改是否解決了錯誤(而不是他以不同的方式做)。

BTW。記錄已到位,記錄的路徑似乎確定 - 抱歉沒有提到這一點。我認爲這是理所當然的,並發現它不必要地複雜問題中的代碼。

感謝您的有用答案。

3

我剛剛遇到同樣的問題。我認爲它必須與寫訪問權限有關。我在嘗試寫入c:\時遇到了錯誤,但在更改爲D:\時,一切正常。 顯然Java的沒有寫權限我的系統驅動器(運行Windows 7安裝在C :)

+0

同意。當引用C:\ Users \ user \ Desktop中的文件時,我遇到了同樣的錯誤...但是當將文件移動到C:\ temp時,問題已解決,因此肯定可能是與權限相關的問題。 – Imre 2017-10-10 09:57:30

3

下面是測試程序我用

import java.io.File; 
public class TestWrite { 

    public static void main(String[] args) { 
     if (args.length!=1) { 
      throw new IllegalArgumentException("Expected 1 argument: dir for tmp file"); 
     } 
     try { 
      File.createTempFile("bla",".tmp",new File(args[0])); 
     } catch (Exception e) { 
      System.out.println("exception:"+e); 
      e.printStackTrace(); 
     } 
    } 
} 
+0

如果通過解決此問題的答案不能幫助您,則應該爲您的問題開一個新問題。如果您將問題作爲對此問題的答案發布,則不太可能得到答案。 – Turismo 2011-02-08 08:54:01

1

僅供參考,當我的文件名有冒號的時間戳時,例如myfile_HH:mm:ss.csv刪除冒號解決了問題。

相關問題