java.io.IOException 的可能原因是什么:“文件名、目录名或卷标语法不正确”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/131901/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are possible reasons for java.io.IOException: "The filename, directory name, or volume label syntax is incorrect"
提问by Turismo
I am trying to copy a file using the following code:
我正在尝试使用以下代码复制文件:
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);
}
For some users the targetFile.createNewFile
results in this exception:
对于某些用户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)
Filename and directory name seem to be correct. The directory targetPath
is even checked for existence before the copy code is executed and the filename looks like this: AB_timestamp.xml
文件名和目录名似乎是正确的。在targetPath
执行复制代码之前,甚至会检查该目录是否存在,文件名如下所示:AB_timestamp.xml
The user has write permissions to the targetPath
and can copy the file without problems using the OS.
用户具有写入权限,targetPath
并且可以使用操作系统复制文件而不会出现问题。
As I don't have access to a machine this happens on yet and can't reproduce the problem on my own machine I turn to you for hints on the reason for this exception.
由于我无法访问机器,这种情况发生并且无法在我自己的机器上重现该问题,因此我向您寻求有关此异常原因的提示。
采纳答案by Alexander
Try this, as it takes more care of adjusting directory separator characters in the path between targetPath and filename:
试试这个,因为它更注意调整 targetPath 和 filename 之间路径中的目录分隔符:
File targetFile = new File(targetPath, filename);
回答by The Archetypal Paul
Do you check that the targetPath is a directory, or just that something exists with that name? (I know you say the user can copy it from the operating system, but maybe they're typing something else).
您是否检查 targetPath 是一个目录,还是仅存在具有该名称的内容?(我知道你说用户可以从操作系统复制它,但也许他们正在输入其他内容)。
Does targetPath end with a File.separator already?
targetPath 是否已经以 File.separator 结尾?
(It would help if you could log and tell us what the value of targetPath and filename are on a failing case)
(如果您可以记录并告诉我们 targetPath 和 filename 的值在失败案例中的值会有所帮助)
回答by Mario Ortegón
Maybe the problem is that it is copying the file over the network, to a shared drive? I think java can have problems when writing files using NFS when the path is something like \mypc\myshared folder.
也许问题在于它正在通过网络将文件复制到共享驱动器?我认为当路径类似于 \mypc\myshared 文件夹时,Java 在使用 NFS 写入文件时可能会出现问题。
What is the path where this problem happens?
发生此问题的路径是什么?
回答by gizmo
Try adding some logging to see exactly what is the name and path the file is trying to create, to ensure that the parent is well a directory.
尝试添加一些日志记录以准确查看文件试图创建的名称和路径,以确保父目录是一个目录。
In addition, you can also take a look at Channels instead of using a loop. ;-)
此外,您还可以查看 Channels 而不是使用循环。;-)
回答by Lars Westergren
You say "for some users" - so it works for others? What is the difference here, are the users running different instances on different machines, or is this a server that services concurrent users?
你说“对于某些用户” - 所以它适用于其他人?这里有什么区别,用户是在不同的机器上运行不同的实例,还是这是一个为并发用户提供服务的服务器?
If the latter, I'd say it is a concurrency bug somehow - two threads check try to create the file with WinNTFileSystem.createFileExclusively(Native Method) simultaniously.
如果是后者,我会说这是一个并发错误 - 两个线程检查尝试同时使用 WinNTFileSystem.createFileExclusively(Native Method) 创建文件。
Neither createNewFile or createFileExclusively are synchronized when I look at the OpenJDK source, so you may have to synchronize this block yourself.
当我查看 OpenJDK 源代码时,createNewFile 或 createFileExclusively 都没有同步,因此您可能需要自己同步此块。
回答by xmjx
Try to create the file in a different directory - e.g. "C:\" after you made sure you have write access to that directory. If that works, the path name of the file is wrong.
在确定您对该目录具有写访问权限后,尝试在不同的目录中创建文件 - 例如“C:\”。如果可行,则文件的路径名是错误的。
Take a look at the comment in the Exception and try to vary all the elements in the path name of the file. Experiment. Draw conclusions.
查看异常中的注释并尝试改变文件路径名中的所有元素。实验。得出结论。
回答by bernardn
Maybe the file already exists. It could be the case if your timestamp resolution is not good enough. As it is an IOException that you are getting, it might not be a permission issue (in which case you would get a SecurityException).
也许文件已经存在。如果您的时间戳分辨率不够好,可能就是这种情况。由于您收到的是 IOException,因此可能不是权限问题(在这种情况下,您会收到 SecurityException)。
I would first check for file existence before trying to create the file and try to log what's happening.
在尝试创建文件之前,我会首先检查文件是否存在并尝试记录正在发生的事情。
Look at public boolean createNewFile()for more information on the method you are using.
查看public boolean createNewFile()以获取有关您正在使用的方法的更多信息。
回答by Turismo
As I was not able to reproduce the error on my own machine or get hands on the machine of the user where the code failed I waited until now to declare an accepted answer. I changed the code to the following:
由于我无法在自己的机器上重现该错误,也无法在代码失败的用户的机器上进行操作,因此我一直等到现在才宣布接受的答案。我将代码更改为以下内容:
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);
}
After that it worked for the user reporting the problem.
之后,它适用于报告问题的用户。
So it seems Alexanders answer did the trick - although I actually use a slightly different constructor than he gave, but along the same lines.
所以看起来亚历山大的回答成功了——虽然我实际上使用了一个与他给出的略有不同的构造函数,但沿着相同的路线。
I yet have to talk that user into helping me verifying that the code change fixed the error (instead of him doing something differently) by running the old version again and checking if it still fails.
我还必须说服那个用户通过再次运行旧版本并检查它是否仍然失败来帮助我验证代码更改是否修复了错误(而不是他做不同的事情)。
btw. logging was in place and the logged path seemed ok - sorry for not mentioning that. I took that for granted and found it unnecessarily complicated the code in the question.
顺便提一句。日志记录到位,记录的路径似乎没问题 - 很抱歉没有提到这一点。我认为这是理所当然的,并发现它不必要地使问题中的代码复杂化。
Thanks for the helpful answers.
感谢您提供有用的答案。
回答by Sensei
I just encountered the same problem. I think it has to something do with write access permission. I got the error while trying to write to c:\ but on changing to D:\ everything worked fine. Apparently Java did not have permission to write to my System Drive (Running Windows 7 installed on C:)
我刚刚遇到了同样的问题。我认为这与写访问权限有关。我在尝试写入 c:\ 时遇到错误,但在更改为 D:\ 时一切正常。显然 Java 无权写入我的系统驱动器(运行安装在 C 上的 Windows 7:)
回答by w.pasman
Here is the test program I use
这是我使用的测试程序
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();
}
}
}