Каковы возможные причины исключения 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
и можно без проблем скопировать файл с помощью ОС.
Поскольку у меня пока нет доступа к машине, это происходит, и я не могу воспроизвести проблему на своей машине, я обращаюсь к вам за подсказками о причине этого исключения.
Решение
Попробуйте это, так как при этом требуется больше внимания к настройке символов-разделителей каталогов в пути между targetPath и именем файла:
File targetFile = new File(targetPath, filename);
Другие советы
Я только что столкнулся с той же проблемой.Я думаю, это как-то связано с разрешением на запись.Я получил ошибку при попытке записи в c:\, но при переходе на D:\ все работало нормально.Судя по всему, у Java не было разрешения на запись на мой системный диск (под управлением Windows 7, установленной на C :)
К вашему сведению, я получил это тогда, когда имена моих файлов имели метку времени с двоеточиями, т.е. myfile_HH:mm:ss.csv
Удаление двоеточий решило проблему.
Вот тестовая программа, которую я использую
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();
}
}
}
Попробуйте создать файл в другом каталоге, например.«C:» после того, как вы убедились, что у вас есть доступ на запись в этот каталог.Если это работает, значит, путь к файлу неверен.
Взгляните на комментарий в Исключении и попробуйте изменить все элементы пути к файлу.Экспериментируйте.Делать выводы.
Проверяете ли вы, что targetPath является каталогом или просто существует что-то с таким именем?(Я знаю, вы говорите, что пользователь может скопировать его из операционной системы, но, возможно, он набирает что-то другое).
TargetPath уже заканчивается File.separator?
(Было бы полезно, если бы вы могли войти и сообщить нам, каково значение targetPath и имени файла в случае сбоя)
Может быть, проблема в том, что он копирует файл по сети, на общий диск?Я думаю, что у Java могут возникнуть проблемы при записи файлов с использованием NFS, если путь похож на папку \mypc\myshared.
Каков путь возникновения этой проблемы?
Попробуйте добавить журналирование, чтобы точно узнать, какое имя и путь пытается создать файл, и убедиться, что родительский файл является каталогом.
Кроме того, вы также можете просмотреть каналы вместо использования цикла.;-)
Вы говорите «для некоторых пользователей» — значит, для других это работает?Какая здесь разница: пользователи запускают разные экземпляры на разных машинах или это сервер, который обслуживает одновременных пользователей?
Если последнее, я бы сказал, что это какая-то ошибка параллелизма - проверка двух потоков пытается одновременно создать файл с помощью WinNTFileSystem.createFileExclusively(Native Method).
Ни createNewFile, ни createFileExclusively не синхронизируются, когда я смотрю на исходный код OpenJDK, поэтому вам, возможно, придется синхронизировать этот блок самостоятельно.
Возможно, файл уже существует.Это может быть в том случае, если разрешение вашей временной метки недостаточно хорошее.Поскольку вы получаете исключение IOException, это может не быть проблемой с разрешением (в этом случае вы получите SecurityException).
Я бы сначала проверил существование файла, прежде чем пытаться его создать, и попытался записать, что происходит.
Посмотри на общедоступное логическое значение createNewFile() для получения дополнительной информации о методе, который вы используете.
Поскольку мне не удалось воспроизвести ошибку на своей машине или получить доступ к машине пользователя, на которой произошел сбой кода, я ждал до сих пор, чтобы объявить принятый ответ.Я изменил код на следующий:
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);
}
После этого это сработало для пользователя, сообщившего о проблеме.
Итак, кажется, что ответ Александра сработал - хотя на самом деле я использую немного другой конструктор, чем он дал, но в том же духе.
Мне еще предстоит уговорить этого пользователя помочь мне убедиться, что изменение кода устранило ошибку (вместо того, чтобы он сделал что-то по-другому), снова запустив старую версию и проверив, не дает ли она по-прежнему сбой.
кстати.регистрация была на месте, и записанный путь выглядел нормально - извините, что не упомянул об этом.Я принял это как должное и обнаружил, что это излишне усложняет код в вопросе.
Спасибо за полезные ответы.
Очень похожая ошибка:- "...java.io.IOИсключение:Имя файла, имя каталога или синтаксис метки тома неверно »было создано в Eclipse для меня, когда в домашней обстановке Tomcat была обратная черта обучения.
Незначительное редактирование предложено по адресу: - http://www.coderanch.com/t/556633/Tomcat/java-io-IOException-filename-directoryисправил это для меня.
Удалите все специальные символы из имени файла/папки в полном пути.