File.mkdir или mkdirs return false - причина?
Почему file.mkdir возвращает false?
Google указывает, что может быть несколько причин (например, безопасность, разрешения, путь и т.д.).
Мои вопросы:
- Как найти точную причину возврата false?
- Если безопасность/разрешения являются причиной, то почему SecurityException не выбрасывается?
Ответы
Ответ 1
Если безопасность/разрешения являются причиной, то почему не генерируется SecurityException (что упоминается в javadoc)?
SecurityException
генерируется, когда у вас нет разрешения уровня JVM на что-либо, а не на уровне ОС
Есть ли способ найти точную причину возврата false?
Нет, AFAIK. Единственный способ узнать это - самостоятельно проверить разрешения для каталога, убедиться, что он не существует, прежде чем вызывать их, проверить, существует ли родительский каталог и т.д.
Однако, если вы используете Java 7 или выше, вы можете использовать вместо этого NIO для создания каталога. В частности, Files.createDirectory
:
File dir = new File("mydir");
Files.createDirectory(dir.toPath());
Если вы хотите использовать NIO полностью без использования java.io.File
, вы можете использовать Paths.get
для создания Path
:
Path dir = Paths.get("mydir");
Files.createDirectory(dir);
В обоих случаях, если каталог не может быть создан, он выдаст IOException
с точной причиной, по которой операция не удалась.
Это верно для большинства методов в Files
, поэтому рекомендуется использовать его, а не методы в классе File
.
Ответ 2
mkdir и mkdirs возвращают false, если каталог уже существует, поэтому это может быть одной из причин отказа.
Если вы используете Java 7, вы можете использовать класс Files. Он генерирует IOException при ошибке с довольно хорошими описаниями.
Files.createDirectory(file.toPath());
Ответ 3
-
Нет, нет способа найти точную причину mkdirs()
возвращает false, по крайней мере, не изнутри Java, так как это, вероятно, зависит от ОС.
-
A SecurityException
вызывается, если есть нарушение безопасности в методах SecurityManager
checkRead()
и checkWrite()
. Исключение не выбрасывается, если есть проблема с разрешениями ОС.
Кроме того, обратите внимание, что если вы вызываете File.mkdir()
, а родительский каталог не существует, mkdir()
возвращает false. Однако вызов File.mkdirs()
приведет к созданию несуществующих родительских каталогов.
Ответ 4
Вот кое-что специфичное для Windows: в моем случае метод file.mkdir()
не NoSuchFileException
с NoSuchFileException
потому что я пытался создать вложенную структуру каталогов напрямую (например, results\results_ddMMyyyy
без предварительного создания каталога results
) в Windows.
Тем не менее, точно такой же код работал на моем Mac, т.е. такого исключения не было на Mac, и промежуточный каталог results
неявно создавался методом file.mkdir()
.
Надеюсь, это поможет кому-то в будущем.
Ответ 5
У меня был сбой mkdirs() в Windows на пути UNC. Код выглядит так:
public File getOldDirectoryPath(String root, String name)
{
File fulldir = new File(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = fulldir.exists())) {
if (20 == retry) break
if (!fulldir.mkdirs()) {
sleep(100)
fulldir = new File(root, name)
}
}
}
return fulldir.exists() ? fulldir : null
}
Похоже, что происходит какое-то кеширование, в случае если с существующим() возвращается ложное (не существует), но в файловой системе происходит сбой mkdir, поскольку он существует. Повторное создание записи File() или увеличение времени ожидания не имело значения.
Я обнаружил плагин наasticsearch, чтобы исправить проблему SMB в Windows. Исследуя решение, он использует nio.file вместо io.File. Переписывание функции устранило проблему:
public File getDirectoryPath(String root, String name)
{
Path fulldir = Paths.get(root, name)
boolean created = false
int retry = 0
while (!created) {
retry++
if (!(created = Files.isDirectory(fulldir))) {
if (20 == retry) break
try {
Files.createDirectories(fulldir)
} catch (Throwable thx) {
// error handling
}
}
}
return fulldir.toFile()
}
createDirectories() иногда завершается ошибкой, но восстанавливает, где mkdirs() не делает.