【问题标题】:What are possible reasons for java.io.IOException: "The filename, directory name, or volume label syntax is incorrect"java.io.IOException 的可能原因是什么:“文件名、目录名或卷标语法不正确”
【发布时间】:2008-09-25 07:22:28
【问题描述】:

我正在尝试使用以下代码复制文件:

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的写入权限,并且可以在使用操作系统时毫​​无问题地复制文件。

由于我无法访问机器,因此这种情况发生在我自己的机器上,并且无法在我自己的机器上重现该问题,因此我向您寻求有关此异常原因的提示。

【问题讨论】:

    标签: java exception file-io


    【解决方案1】:

    当文件名的时间戳带有冒号时,可能会发生这种情况,例如。 myfile_HH:mm:ss.csv 删除冒号解决了这个问题。

    【讨论】:

    • 这对我有用。 SAP HANA 使用此方法创建日志文件,而我的表名中的冒号导致该方法失败
    • 在文件名中使用冒号是我来到这里的原因:p
    【解决方案2】:

    试试这个,因为它更注意调整 targetPath 和文件名之间路径中的目录分隔符:

    File targetFile = new File(targetPath, filename);
    

    【讨论】:

      【解决方案3】:

      我刚刚遇到了同样的问题。我认为这与写访问权限有关。我在尝试写入 c:\ 时遇到错误,但在更改为 D:\ 时一切正常。 显然 Java 没有权限写入我的系统驱动器(运行安装在 C 上的 Windows 7:)

      【讨论】:

      • 同意。在引用 C:\Users\user\Desktop... 的文件时,我遇到了同样的错误,但是当将文件移动到 C:\temp 时,问题得到了解决,因此肯定是权限相关的问题。
      【解决方案4】:

      这是我使用的测试程序

      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();
              }
          }
      }
      

      【讨论】:

      • 如果解决此问题的答案对您没有帮助,您应该为您的问题打开一个新问题。如果您将您的问题作为此问题的答案发布,则您不太可能得到答案。
      【解决方案5】:

      尝试在不同的目录中创建文件 - 例如“C:\”确保您对该目录具有写访问权。如果这样的话,文件的路径名是错误的。

      查看异常中的注释并尝试改变文件路径名中的所有元素。实验。得出结论。

      【讨论】:

        【解决方案6】:

        删除完整路径中文件/文件夹名称中的所有特殊字符。

        【讨论】:

        • 请添加更多关于如何执行此操作的说明。 OP 说“我无法使用机器”,那是十多年前(!)
        【解决方案7】:

        您是否检查 targetPath 是一个目录,或者只是存在具有该名称的东西? (我知道您说用户可以从操作系统复制它,但也许他们正在输入其他内容)。

        targetPath 是否已经以 File.separator 结尾?

        (如果您可以记录并告诉我们在失败案例中 targetPath 和 filename 的值是什么,这将有所帮助)

        【讨论】:

          【解决方案8】:

          也许问题在于它通过网络将文件复制到共享驱动器?当路径类似于 \mypc\myshared 文件夹时,我认为 java 在使用 NFS 写入文件时可能会出现问题。

          这个问题发生的路径是什么?

          【讨论】:

            【解决方案9】:

            尝试添加一些日志以查看文件试图创建的确切名称和路径,以确保父目录是一个目录。

            此外,您还可以查看 Channels 而不是使用循环。 ;-)

            【讨论】:

              【解决方案10】:

              您说“对于某些用户”——所以它适用于其他用户?这里有什么区别,用户是在不同的机器上运行不同的实例,还是这是为并发用户提供服务的服务器?

              如果是后者,我会说这是一个并发错误 - 两个线程检查尝试同时使用 WinNTFileSystem.createFileExclusively(Native Method) 创建文件。

              我看OpenJDK源码时createNewFile和createFileExclusively都没有同步,所以你可能需要自己同步这个block。

              【讨论】:

              • 逗号在 Windows 上是不允许的,但在其他操作系统上是允许的。也许这就是原因?
              【解决方案11】:

              可能文件已经存在。如果您的时间戳分辨率不够好,可能会出现这种情况。由于您收到的是 IOException,因此可能不是权限问题(在这种情况下您会收到 SecurityException)。

              我会先检查文件是否存在,然后再尝试创建文件并尝试记录发生的情况。

              查看public boolean createNewFile(),了解有关您使用的方法的更多信息。

              【讨论】:

              • API 实际上说,如果文件已经存在,它不会抛出 IOException,而在这种情况下只是返回 false。
              【解决方案12】:

              由于我无法在我自己的机器上重现错误,或者无法使用代码失败的用户的机器,我一直等到现在才宣布接受的答案。 我将代码更改为以下内容:

              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 的回答起到了作用——虽然我实际上使用的构造函数与他给出的构造函数略有不同,但大致相同。

              我还需要说服该用户通过再次运行旧版本并检查它是否仍然失败来帮助我验证代码更改是否修复了错误(而不是他做一些不同的事情)。

              顺便说一句。日志记录已经到位,并且记录的路径似乎没问题 - 抱歉没有提到这一点。我认为这是理所当然的,并发现它不必要地使问题中的代码复杂化。

              感谢您提供有用的答案。

              【讨论】:

                【解决方案13】:

                一个非常相似的错误:- “ ... java.io.IOException:文件名、目录名或卷标语法不正确” 当 TOMCAT 主页设置有训练反斜杠时,在 Eclipse 中为我生成了。

                建议的小修改:- http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directory 为我修好了。

                【讨论】:

                  猜你喜欢
                  • 2015-02-15
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-06-30
                  • 2019-05-24
                  • 2019-09-30
                  • 2018-10-31
                  • 1970-01-01
                  相关资源
                  最近更新 更多