Проверьте, существует ли файл перед вызовом openFileInput
Чтобы прочитать файл в Android из личной области вашего приложения, вы используете функциюopenFileInput()
,
У меня вопрос, есть ли способ проверить, существует ли этот файл перед вызовом этой функции? Функция может бросить FileNotFoundException
, но я чувствую, что хочу позвонить, а затем делать что-то на основе try
-catch
плохая практика
С помощью File.exist()
кажется странным также использовать, так как это потребовало бы создания экземпляра класса, и я не уверен, что если просто передать ему имя файла, он найдет файл в приватной области моего телефона.
3 ответа
public boolean fileExists(Context context, String filename) {
File file = context.getFileStreamPath(filename);
if(file == null || !file.exists()) {
return false;
}
return true;
}
РЕДАКТИРОВАТЬ:
Кроме того, здесь есть еще один способ для файлов во внешнем хранилище.
String fileUrl = "/appname/data.xml";
String file = android.os.Environment.getExternalStorageDirectory().getPath() + fileUrl;
File f = new File(file);
if(f.exists())
return;
Функция может быть вызвана через FileNotFoundException, но я чувствую, что это нужно вызывать, а затем делать что-то на основе попытки перехвата - плохая практика.
Я не согласен. ИМО, это проверка, существует ли файл перед открытием, что является плохой практикой. Сравните эти две версии кода:
File f = new File("someFile");
InputStream is;
Версия № 1
if (f.exists()) {
is = new FileInputStream(f);
...
} else {
System.err.println("Doesn't exist");
}
Версия № 2
try {
is = new FileInputStream(f);
...
} catch (FileNotFoundException ex) {
System.err.println("Doesn't exist");
}
Существует ряд проблем с первой версией:
Версия #1 делает дополнительный системный вызов, когда вы звоните
f.exists()
, Это делает первую версию медленнее в среднем, если только не существует высокой вероятности того, что файл не будет существовать.Версия № 1 имеет состояние гонки. Если какой-то внешний процесс удаляет файл примерно в одно и то же время, вы можете получить
file.exists()
возвращая истину, а затемFileInputStream
бросок конструктораFileNotFoundException
, Это такое состояние гонки, которое может быть использовано для нарушения безопасности, если рассматриваемый файл критичен к безопасности. (На самом деле, есть и второе условие гонки, когда файл создается иfile.exists()
возвращает false, если последующая попытка открыть его будет успешной. Но это состояние гонки, вероятно, безвредно.)
Еще одна проблема заключается в том, что FileInputStream
объявлен броском IOException
, Тестирование, чтобы увидеть, существует ли файл, имеет дело только с одним из возможных режимов отказа. Твой код придется поймать и разобраться с этими другими IOException
в любом случае.
@Pieces прокомментировал:
Исключения должны быть для случаев, когда что-то действительно идет не так, что вы не можете контролировать. В этом случае я полностью контролирую это.
На самом деле, вы не имеете полного контроля над этим. Конечно, не в общем случае. Даже в вашем конкретном случае условия гонки все еще возможны в теории.
Но настоящая проблема с этим типом мышления состоит в том, что вы в конечном итоге перепрыгиваете через обручи, чтобы избежать исключений в ситуациях, когда обработка исключений / исключений является лучшим решением. Это делает код более сложным, менее читаемым, и потенциально более медленным и / или более хрупким.
Нормальная догма выглядит так:
"Исключения должны использоваться только в исключительных ситуациях".
Это не то же самое, что сказать, что ты сказал. Слово "исключительный" на самом деле просто означает "не нормально". Это имеет гораздо более широкое значение, чем "что-то идет не так, что вы не можете контролировать".
Я склонен расширять догму следующим образом:
Исключения не должны использоваться для нормального управления потоком.
Исключения не следует использовать, если они в среднем окажутся слишком дорогими.
Исключения следует использовать, если тесты, которые вы будете использовать, чтобы избежать их, не являются надежными.
Исключения следует использовать, если тесты, которые вы будете использовать, чтобы избежать их, в среднем слишком дороги.
Исключения следует использовать, если они значительно упрощают ваш код (по модулю выше). И критерий простоты - читаемость кода средним программистом на Java.
(Примечание - "в среднем" и "слишком дорого" ...)
Теперь можно спорить, пока коровы не вернутся домой, о том, насколько исключительным должно быть событие, но я полагаю, что это действительно вопрос баланса относительной простоты подходов (в контексте) и средних затрат на производительность (в контексте).). Любое догматическое правило, которое не учитывает компромиссы и контекст, в некоторых случаях может причинить вам вред.
Это работа для меня.
try {
FileInputStream fis = openFileInput(String filename);
// ... do something
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
но случается, иногда, он возвращает исключение то же самое... работа с ADB.