Quais são as possíveis razões para java.io.IOException: “O nome do arquivo, o nome do diretório ou a syntax do label do volume está incorreta”

Eu estou tentando copiar um arquivo usando o seguinte código:

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

Para alguns usuários, o targetFile.createNewFile resulta nesta exceção:

 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) 

Nome do arquivo e nome do diretório parecem estar corretos. O diretório targetPath é ainda verificado quanto à existência antes que o código de cópia seja executado e o nome do arquivo se pareça com isto: AB_timestamp.xml

O usuário tem permissions de gravação para o targetPath e pode copiar o arquivo sem problemas usando o sistema operacional.

Como não tenho access a uma máquina, isso acontece ainda e não consigo reproduzir o problema em minha própria máquina. Eu ligo para você para obter sugestões sobre o motivo dessa exceção.

Tente isso, pois é mais necessário ajustar os caracteres do separador de diretório no caminho entre targetPath e filename:

 File targetFile = new File(targetPath, filename); 

Acabei de encontrar o mesmo problema. Eu acho que tem que fazer alguma coisa com permissão de access de gravação. Eu tenho o erro ao tentar escrever para c: \ mas ao mudar para D: \ tudo funcionou bem. Aparentemente, o Java não tem permissão para gravar na minha unidade do sistema (executando o Windows 7 instalado no C 🙂

Aqui está o programa de teste que eu uso

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

Tente criar o arquivo em um diretório diferente – por exemplo, “C: \” depois de ter certeza de que você tem access de gravação a esse diretório. Se isso funcionar, o nome do caminho do arquivo está errado.

Dê uma olhada no comentário na Exceção e tente variar todos os elementos no nome do caminho do arquivo. Experimentar. Tire conclusões.

FYI, eu tenho então quando meus nomes de arquivos tinham um timestamp com dois pontos, ou seja, myfile_HH:mm:ss.csv Removendo os dois pontos corrigiu o problema.

Você verifica se o targetPath é um diretório ou apenas que existe algo com esse nome? (Eu sei que você diz que o usuário pode copiá-lo do sistema operacional, mas talvez eles estejam digitando outra coisa).

O targetPath termina com um File.separator já?

(Ajudaria se você pudesse logar e nos dizer qual é o valor de targetPath e filename em um caso de falha)

Talvez o problema é que ele está copiando o arquivo através da rede, para uma unidade compartilhada? Eu acho que o java pode ter problemas ao escrever arquivos usando o NFS quando o caminho é algo como pasta \ mypc \ myshared.

Qual é o caminho onde esse problema acontece?

Tente adicionar alguns registros para ver exatamente qual é o nome e o caminho que o arquivo está tentando criar, para garantir que o pai seja um diretório.

Além disso, você também pode dar uma olhada nos canais em vez de usar um loop. 😉

Você diz “para alguns usuários” – então funciona para os outros? Qual é a diferença aqui: os usuários estão executando instâncias diferentes em máquinas diferentes ou este é um servidor que atende usuários simultâneos?

Se este último, eu diria que é um bug de simultaneidade de alguma forma – dois tópicos verificar tentam criar o arquivo com WinNTFileSystem.createFileExclusively (Native Method) simultaneamente.

Nem createNewFile ou createFileExclusively são sincronizados quando eu olho para a fonte OpenJDK, então você pode ter que sincronizar este bloco sozinho.

Talvez o arquivo já exista. Pode ser o caso se a resolução do timestamp não for boa o suficiente. Como é uma IOException que você está recebendo, pode não ser um problema de permissão (nesse caso, você obteria uma SecurityException).

Primeiro, verifiquei a existência do arquivo antes de tentar criar o arquivo e tente registrar o que está acontecendo.

Olhe para public booleano createNewFile () para mais informações sobre o método que você está usando.

Como não fui capaz de reproduzir o erro em minha própria máquina ou colocar as mãos na máquina do usuário onde o código falhou, esperei até agora para declarar uma resposta aceita. Eu mudei o código para o seguinte:

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

Depois disso, funcionou para o usuário reportar o problema.

Então parece que a resposta de Alexanders fez o truque – embora eu realmente use um construtor ligeiramente diferente do que ele deu, mas na mesma linha.

Eu ainda tenho que falar com esse usuário para me ajudar a verificar se a alteração do código corrigiu o erro (em vez de ele fazer algo diferente) executando a versão antiga novamente e verificando se ela ainda falha.

btw. logging estava no lugar e o caminho logado parecia ok – desculpe por não mencionar isso. Eu tomei como garantido e achei desnecessariamente complicado o código na questão.

Obrigado pelas respostas úteis.

Um erro muito semelhante: – “… java.io.IOException: O nome do arquivo, o nome do diretório ou a syntax do label do volume está incorreta” foi gerado no Eclipse para mim quando a configuração inicial do TOMCAT tinha uma barra invertida de treinamento.

A menor edição sugerida em: – http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directory corrigiu para mim.