Каковы возможные причины для java.io.IOException: "Имя файла, имя каталога или синтаксис метки тома неверны"

Я пытаюсь скопировать файл, используя следующий код:

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 и может без проблем копировать файл с помощью ОС.

Поскольку у меня нет доступа к машине, это происходит еще и не может воспроизвести проблему на моем собственном компьютере. Я обращаюсь к вам за подсказками по причине этого исключения.

Ответ 1

Попробуйте это, так как требуется более тщательное регулирование символов разделителя каталога в пути между targetPath и именем файла:

File targetFile = new File(targetPath, filename);

Ответ 2

Я столкнулся с той же проблемой. Я думаю, что он должен что-то делать с разрешением на доступ к записи. Я получил ошибку при попытке написать c: \, но при смене на D:\все работало нормально. По-видимому, у Java не было разрешения на запись на мой системный диск (запуск Windows 7, установленный на C:)

Ответ 3

FYI, я получил тогда, когда мои имена файлов имели временную метку с двоеточиями, то есть myfile_HH:mm:ss.csv Удаление двоеточей исправило проблему.

Ответ 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: \" после того, как вы убедитесь, что у вас есть доступ на запись к этому каталогу. Если это работает, путь к файлу неправильный.

Взгляните на комментарий в Exception и попробуйте изменить все элементы в имени пути файла. Эксперимент. Сделайте выводы.

Ответ 6

Проверяете ли вы, что targetPath является каталогом или просто что-то существует с этим именем? (Я знаю, вы говорите, что пользователь может скопировать его из операционной системы, но, возможно, они набирают что-то еще).

Заканчивается ли targetPath с помощью File.separator?

(Это поможет, если вы сможете войти в систему и сообщить нам, что значение targetPath и имени файла находится в неудачном случае)

Ответ 7

Возможно, проблема в том, что он копирует файл по сети, на общий диск? Я думаю, что java может иметь проблемы при написании файлов с использованием NFS, когда путь является чем-то вроде папки \mypc\myshared.

Каков путь, в котором эта проблема возникает?

Ответ 8

Попробуйте добавить некоторые протоколирования, чтобы точно увидеть, что такое имя и путь, который пытается создать файл, чтобы обеспечить корректность каталога.

Кроме того, вы можете также взглянуть на каналы вместо использования цикла.; -)

Ответ 9

Вы говорите "для некоторых пользователей" - так это работает для других? В чем здесь разница: пользователи, которые запускают разные экземпляры на разных компьютерах, или это сервер, который обслуживает одновременных пользователей?

Если последнее, я бы сказал, что это ошибка concurrency как-то - проверка двух потоков попытается создать файл с помощью WinNTFileSystem.createFileExclusive(Native Method) одновременно.

Ни CreateNewFile, ни CreateFileExclusive не синхронизируются, когда я смотрю на источник OpenJDK, поэтому вам может понадобиться синхронизировать этот блок самостоятельно.

Ответ 10

Возможно, файл уже существует. Это может быть так, если ваше временное разрешение недостаточно. Поскольку это IOException, которое вы получаете, это может быть не проблема разрешения (в этом случае вы получите SecurityException).

Сначала я должен проверить наличие файла, прежде чем пытаться создать файл, и попытаться записать, что происходит.

Посмотрите public boolean createNewFile() для получения дополнительной информации о методе, который вы используете.

Ответ 11

Поскольку я не смог воспроизвести ошибку на своей собственной машине или получить доступ к машине пользователя, где произошел сбой кода, я подождал до сих пор, чтобы объявить принятый ответ. Я изменил код на следующее:

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 сделал трюк - хотя на самом деле я использую немного другой конструктор, чем он дал, но по тем же направлениям.

Мне еще нужно поговорить с этим пользователем, чтобы помочь мне проверить, что изменение кода исправило ошибку (вместо того, чтобы делать что-то по-другому), снова перезапустив старую версию и проверив, не по-прежнему ли она не работает.

кстати. запись была на месте, и путь, записанный в журнал, выглядел нормально - извините, не упомянув об этом. Я воспринял это как должное и нашел, что это излишне усложняет код в вопросе.

Спасибо за полезные ответы.

Ответ 12

Очень похожая ошибка: -   "... java.io.IOException: имя файла, имя каталога или синтаксис метки тома неверно" был создан в Eclipse для меня, когда домашняя установка TOMCAT имела обратную косую черту.

Небольшое редактирование, предлагаемое по адресу: -  http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directory исправил это для меня.

Ответ 13

Удалите все специальные символы в имени файла/папки в полном пути.