views:

3743

answers:

11

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:

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

The user has write permissions to the targetPath and can copy the file without problems using the OS.

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.

A: 

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).

Does targetPath end with a File.separator already?

(It would help if you could log and tell us what the value of targetPath and filename are on a failing case)

Paul
A: 

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.

What is the path where this problem happens?

Mario Ortegón
A: 

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. ;-)

gizmo
A: 

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.

Neither createNewFile or createFileExclusively are synchronized when I look at the OpenJDK source, so you may have to synchronize this block yourself.

Lars Westergren
A: 

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.

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.

xmjx
A: 

It looks like the directoryName + the fileName is creating an invalid file path.

GavinCattell
A: 

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).

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.

bernardn
The API actually says that it won't throw an IOException if the file already exists but simply returns false in this case.
Turismo
+2  A: 

Try this, as it takes more care of adjusting directory separator characters in the path between targetPath and filename:

File targetFile = new File(targetPath, filename);
Alexander
A: 

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.

Turismo
A: 

hi try creating a file with name as test?.mp4

A: 

I just encountered the same problem. I think it has to to 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:)

Sensei