Подтвердить что ты не робот

Проверьте, существует ли файл перед вызовом openFileInput

Чтобы прочитать файл в Android из вашей частной области хранения приложений, вы используете функцию openFileInput().

Мой вопрос в том, есть ли способ проверить, существует ли этот файл перед вызовом этой функции? Функция может вызывать FileNotFoundException, но мне нравится называть это, а затем делать что-то, основанное на try - catch, является плохой практикой.

Использование File.exist() кажется странным для использования, так как для этого потребуется создать экземпляр класса, и я не уверен, что просто передать имя файла ему, чтобы он нашел файл в частной области моего телефон.

4b9b3361

Ответ 1

public boolean fileExists(Context context, String filename) {    
    File file = context.getFileStreamPath(filename);
    if(file == null || !file.exists()) {
        return false;
    }
    return true;
}

EDIT:

Кроме того, это другой способ для файлов во внешнем хранилище.

String fileUrl = "/appname/data.xml";
String file = android.os.Environment.getExternalStorageDirectory().getPath() + fileUrl;
File f = new File(file);

if(f.exists())
return;

Ответ 2

  Функция может быть вызвана через 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(), возвращающий true, а затем конструктор FileInputStream, выбрасывающий FileNotFoundException. Это такое состояние гонки, которое можно использовать для нарушения безопасности, если рассматриваемый файл критичен к безопасности.

    (На самом деле, есть и второе условие гонки. Если вы вызываете file.exists() во время создания файла, он может вернуть false. В этом случае вы напечатаете сообщение об ошибке, даже если new FileInputStream мог преуспеть. Расовое состояние, вероятно, безвредно.)

Еще одна проблема заключается в том, что FileInputStream объявлен как бросающий IOException. Тестирование, чтобы увидеть, существует ли файл, имеет дело только с одним из возможных режимов отказа. В любом случае ваш код будет иметь дело с другим IOException.


@Pieces прокомментировал:

Исключения должны быть для случаев, когда что-то действительно идет не так, что вы не можете контролировать. В этом случае я полностью контролирую его.

На самом деле, вы не имеете полного контроля над этим. Конечно, не в общем случае. Даже в вашем конкретном случае условия гонки все еще возможны в теории.

Но настоящая проблема с этим типом мышления заключается в том, что вы в конечном итоге перепрыгиваете через обручи, чтобы избежать исключений в ситуациях, когда обработка исключений/исключений является лучшим решением. Это делает код более сложным, менее читаемым, потенциально более медленным и/или более хрупким.

Нормальная догма выглядит так:

"Исключения следует использовать только в исключительных ситуациях".

Это не то же самое, что сказать, что ты сказал. Слово "исключительный" на самом деле просто означает "не нормально". Это имеет гораздо более широкое значение, чем "что-то идет не так, что вы не можете контролировать".

Я склонен расширять догму следующим образом:

  • Исключения не должны использоваться для нормального управления потоком.

  • Исключения не следует использовать, если они в среднем окажутся слишком дорогими.

  • Исключения следует использовать, если тесты, которые вы будете использовать, чтобы избежать их, не являются надежными.

  • Исключения следует использовать, если тесты, которые вы будете использовать, чтобы избежать их, в среднем слишком дороги.

  • Исключения следует использовать, если они значительно упрощают ваш код (по модулю выше). И критерий простоты - читаем ли код среднестатистический программист на Java.

(Примечание: "в среднем" и "слишком дорого"...)

Теперь можно спорить, пока коровы не вернутся домой, о том, насколько исключительным должно быть событие, но я полагаю, что это действительно вопрос баланса относительной простоты подходов (в контексте) и средних затрат на производительность (в контексте).). Любое догматическое правило, которое не учитывает компромиссы и контекст, в некоторых случаях может причинить вам вред.

Ответ 3

Эта работа для меня.

try {
  FileInputStream fis = openFileInput(String filename);
  // ... do something
try {
    fis.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
} catch (FileNotFoundException e) { 
  e.printStackTrace();
}

но случается, несколько раз он возвращает исключение, то же самое... работает с adb.