Если я вызываю один из методов File.mkdir()
или File.mkdirs()
в Java и возвращает false
, есть ли способ узнать, почему каталог не был создан?
Обнаружение причины сбоя File.mkdirs()
Ответ 1
Не совсем, нет. Если a SecurityException
НЕ выбрасывается, то наиболее вероятной причиной является опечатка в пути, то есть вы случайно указали родительский путь к новым каталогам, которые каким-то образом недействительны.
Я не предполагаю, что вы его завернули в блок try { ... } catch (Exception e)
, где вы не понимаете, что бросается SecurityException
, потому что вы ловите предка SecurityException
, не так ли?
Если у вас есть высокая убежденность в том, что все выглядит правильно, и все еще не удается, я полагаю, вы могли бы просто поставить его в цикл, чтобы повторить, скажем, три раза. Если он по-прежнему не работает, и в зависимости от вашего приложения вы можете поднять какое-то предупреждение на уровне пользовательского интерфейса или зарегистрировать ошибку в файле журнала (при условии, что вы можете записать на нее).
Я полагаю, что возможно, что некоторая более глубокая проблема ввода-вывода не позволяет ему работать, но помимо простого уведомления пользователя о сбое, вы не можете (или действительно должны) делать это на уровне приложения. Если что-то глубже в I/O неправильно, это скорее проблема с системой/аппаратным обеспечением/ОС, или что-то совершенно неудобное, что вы не контролируете, как сбои в подсистеме/службе.
... и если это произойдет, то ответственность IT-специалиста исправить, а не ваше приложение. Если, конечно, ваше приложение каким-то образом не приведет к сбою.
Ответ 2
У меня был сбой 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() не делает.