Проверьте, существует ли файл перед вызовом 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.

Другие вопросы по тегам