#java #nullpointerexception
#java #исключение nullpointerexception
Вопрос:
У меня есть ряд папок, содержащих книги на сервере, к которым я обращаюсь с помощью этого фрагмента кода. Я хочу сделать каждую из этих папок объектом, чтобы позже я мог выполнить некоторую работу с файлами внутри них. Я пытаюсь использовать этот метод для возврата списка папок в виде объектов Book.
public List<Book> getBooks(File folder){
List<Book> books = new ArrayList<Book>();
for (File f : folder.listFiles()){
if (f.isDirectory()){
System.out.println(f.getAbsolutePath() "" f.listFiles());
books.add(new Book(f));
}
}
return books;
}
Оператор println в этом блоке печатает, как и должно быть, прямой путь к папке, а затем адрес памяти вместе с некоторой другой информацией. Однако где-то в папке при вызове listFiles() выводится значение null. Папка, в которой это выполняется, не пуста. Затем эта предположительно пустая папка передается в метод инициализации моего класса.
public Book(File bookFolder) {
this.bookFolder = bookFolder;
this.bookPath = bookFolder.getAbsolutePath();
System.out.println(bookFolder " " bookFolder.listFiles());
for (File f : bookFolder.listFiles()) {
...
}
}
Оператор println в этом блоке выводит точно такой же путь к папке, а затем другой адрес памяти, который также ожидается. Когда он попадает в «пустую» папку, он снова выводит null для адреса памяти.
Теперь, что касается реальной проблемы, строка с циклом for — это то место, где программа завершает работу и выдает исключение NullPointerException, которое даже не описано в документации для метода listFiles.
Почему это может происходить? Кроме того, почему мои непустые папки возвращают значение null?
Комментарии:
1. Трассировки стека существуют не просто так. Прочитайте это, поймите.
2. @Mat — оператор ‘foreach’ (
:
) выдает NPE, если объект, по которому выполняется итерация, равен null (в вашем случае,bookFolder.listFiles()
)3. @skaffman — stacktrace сообщает вам только, где происходит NPE, а не почему. Иногда это очевидно, иногда нет, в зависимости от того, сколько происходит с этой строкой.
4. @Kevin K — спасибо, это был ответ, который я искал. Теперь мне просто нужно выяснить, почему они в первую очередь равны null.
5. В качестве дополнительного примечания, ваши имена переменных сбивают с толку.
book
ЭтоFile
a, и чтобы добавить его в списокbooks
, необходимо создать aBook
из abook
. Я бы посоветовал не путать книги с файлами.
Ответ №1:
В документации к listFiles()
методу четко указано, что он «Возвращает null, если это абстрактное имя пути не обозначает каталог, или если возникает ошибка ввода-вывода».
Одна из наиболее распространенных причин, по которой каталог не может быть указан, заключается в том, что процессу не хватает правильных разрешений. Вы запускаете это от своего имени или в какой-то службе, которая запускается от имени другого пользователя?
Кстати, File
API — отличный пример того, насколько плохой может быть жизнь без исключений.
Комментарии:
1. Другой причиной может быть то, что файл не является каталогом.
2. Ну, в целом это, безусловно, верно! Но, в данном случае, похоже, что соответствующее тестирование выполнено, чтобы исключить это.
3. @erickson Я хотел знать, почему они возвращают null, когда я уверен, что они содержат другие файлы. Путь определенно является каталогом, поскольку я проверяю, чтобы убедиться, что это так, и другие папки на том же сервере нормально работают с этим кодом, поэтому я не думаю, что это проблема с разрешениями.
4. Этот код запускается службой, которая запускает его от имени администратора, что делает меня еще более уверенным, что это не проблема с разрешениями.
5. @erickson — Большое вам спасибо за вашу помощь. Как оказалось, мне, похоже, не хватает места, потому что я открываю так много файлов, похоже, именно поэтому listFiles () начинает возвращать null вместо адресов памяти.
Ответ №2:
Для разработчиков, которые уже включили следующие решения :
- Добавлено разрешение на хранение
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
2. Каталог, из которого вы хотите перечислить файлы, существует.
- Включено разрешение на тестируемом устройстве в настройках разрешений приложения
ПРИВЕДЕННЫЙ НИЖЕ КОД РЕШИТ вашу ПРОБЛЕМУ, если SDK ВАШЕГО УСТРОЙСТВА БОЛЬШЕ ИЛИ РАВЕН ANDROID 10 (Q)
В файл манифеста включите этот код внутри тега
<application android:requestLegacyExternalStorage="true"...</application>
Дайте мне знать, если ваша проблема решена!
Ответ №3:
У меня была аналогичная проблема с dir.listfiles(); возвращал null для папки пользователя AppData Local Microsoft Windows Temporary Internet Files Content.IE5
это была папка, для которой по умолчанию были установлены разрешения «все», запрещающие все
я думаю, что меня подкосил тот факт, что я никогда не ожидал, что там существует какое-либо разрешение Deny.
также для любого неясно, что я подразумеваю под разрешением запретить
когда вы устанавливаете «запретить» для пользовательских разрешений, это переопределяет «разрешить для пользовательских разрешений», если вы не удалите его, и это было при установке Windows 10 Home по умолчанию.
Ответ №4:
Для меня это было вызвано конечными пробелами. Используйте переменную.trim()