web-dev-qa-db-fra.com

Quelles sont les raisons possibles pour Java.io.IOException: "La syntaxe du nom de fichier, du nom de répertoire ou du libellé de volume est incorrecte"

J'essaie de copier un fichier en utilisant le code suivant:

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

Pour certains utilisateurs, le targetFile.createNewFile génère cette 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)

Le nom du fichier et le nom du répertoire semblent être corrects. L'existence du répertoire targetPath est même vérifiée avant que le code de copie ne soit exécuté et que le nom de fichier ressemble à ceci: AB_timestamp.xml

L'utilisateur dispose d'autorisations en écriture sur la variable targetPath et peut copier le fichier sans problème avec le système d'exploitation.

Comme je n'ai pas encore accès à une machine, cela se produit encore et je ne peux pas reproduire le problème sur ma propre machine, je me tourne vers vous pour obtenir des conseils sur la raison de cette exception.

13
Turismo

Essayez ceci, car cela prend plus de soin d'ajuster les caractères de séparation de répertoire dans le chemin entre targetPath et nom de fichier:

File targetFile = new File(targetPath, filename);
5
Alexander

Je viens de rencontrer le même problème. Je pense que cela doit faire quelque chose avec la permission d'accès en écriture. J'ai eu l'erreur en essayant d'écrire sur c:\mais en passant à D:\tout a bien fonctionné. Apparemment, Java n’avait pas l’autorisation d’écrire sur mon lecteur système (Windows 7 installé sous C :)

5
Sensei

Voici le programme de test que j'utilise

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();
        }
    }
}
2
w.pasman

Essayez de créer le fichier dans un autre répertoire - par exemple. "C: \" après vous être assuré que vous avez un accès en écriture à ce répertoire. Si cela fonctionne, le chemin d'accès du fichier est incorrect.

Examinez le commentaire dans l'exception et essayez de faire varier tous les éléments du nom de chemin du fichier. Expérience. Conclure.

1
xmjx

Pour votre information, j'ai eu ensuite lorsque mes noms de fichiers avaient un horodatage avec colons, c.-à-d. myfile_HH:mm:ss.csv La suppression des colons a résolu le problème.

1
Adam Hughes

Vérifiez-vous que le targetPath est un répertoire ou juste que quelque chose existe avec ce nom? (Je sais que vous dites que l'utilisateur peut le copier à partir du système d'exploitation, mais peut-être est-il en train de taper autre chose).

TargetPath se termine-t-il déjà par File.separator?

(Cela aiderait si vous pouviez vous connecter et nous dire quelle est la valeur de targetPath et de nom de fichier sur un cas qui échoue)

0
The Archetypal Paul

Peut-être que le problème est qu'il copie le fichier sur le réseau, sur un lecteur partagé? Je pense que Java peut avoir des problèmes lors de l'écriture de fichiers à l'aide de NFS lorsque le chemin est quelque chose comme le dossier\mypc\myshared.

Quel est le chemin où ce problème se produit?

0
Mario Ortegón

Comme je ne pouvais pas reproduire l'erreur sur ma propre machine ni mettre la main sur la machine de l'utilisateur lorsque le code échouait, j'ai attendu jusqu'à maintenant pour déclarer une réponse acceptée. J'ai changé le code comme suit:

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

Après cela, cela a fonctionné pour l'utilisateur signalant le problème.

Il semble donc que la réponse d’Alexandre a été la solution - bien que j’utilise un constructeur légèrement différent de celui qu’il a donné, mais dans le même sens.

Je dois encore convaincre cet utilisateur de m'aider à vérifier que le changement de code a corrigé l'erreur (au lieu de le faire différemment) en exécutant à nouveau l'ancienne version et en vérifiant si elle échouait toujours.

btw. la journalisation était en place et le chemin d'accès semblait correct - désolé de ne pas l'avoir mentionné. J'ai pris cela pour acquis et j'ai trouvé que cela compliquait inutilement le code dans la question.

Merci pour les réponses utiles.

0
Turismo

Essayez d’ajouter de la journalisation pour voir exactement quel est le nom et le chemin que le fichier tente de créer, afin de vous assurer que le parent est bien un répertoire.

En outre, vous pouvez également consulter Chaînes au lieu d’utiliser une boucle. ;-)

0
gizmo

Vous dites "pour certains utilisateurs" - cela fonctionne donc pour d'autres? Quelle est la différence ici, les utilisateurs exécutent-ils des instances différentes sur des machines différentes ou s'agit-il d'un serveur qui dessert des utilisateurs simultanés?

Si ce dernier point, je dirais que c'est en quelque sorte un bogue d'accès simultané - deux threads vérifient la création simultanée du fichier avec WinNTFileSystem.createFileExclusively (Native Method).

Ni createNewFile, ni createFileExclusively ne sont synchronisés lorsque je regarde la source OpenJDK. Vous devrez donc peut-être synchroniser ce bloc vous-même.

0
Lars Westergren

Une erreur très similaire: - "... Java.io.IOException: la syntaxe du nom de fichier, du nom de répertoire ou de l'étiquette de volume est incorrecte" a été générée dans Eclipse lorsque le paramètre de base de Tomcat comportait une barre oblique inversée d'apprentissage.

La modification mineure suggérée à l'adresse: - http://www.coderanch.com/t/556633/Tomcat/Java-io-IOException-filename-directory l'a corrigé pour moi.

0
MikeRoger

Peut-être que le fichier existe déjà. Ce pourrait être le cas si la résolution de votre horodatage n'est pas suffisante. Comme il s'agit d'une exception IOException, il se peut que ce ne soit pas un problème d'autorisation (auquel cas vous obtiendriez une SecurityException).

Je voudrais d'abord vérifier l'existence du fichier avant d'essayer de créer le fichier et d'essayer de consigner ce qui se passe.

Consultez public boolean createNewFile () pour plus d’informations sur la méthode que vous utilisez.

0
bernardn