getResourceAsStream() против FileInputStream

Я пытался загрузить файл в веб-приложение, и я получаю FileNotFound исключение, когда я использовал FileInputStream, Однако, используя тот же путь, я смог загрузить файл, когда я сделал getResourceAsStream(), В чем разница между этими двумя методами, и почему один работает, а другой нет?

6 ответов

Решение

java.io.File и поддерживает действия в локальной файловой системе диска. Основной причиной вашей проблемы является то, что относительные пути в java.io зависят от текущего рабочего каталога. Т.е. каталог, из которого запускается JVM (в вашем случае это сервер). Это может быть, например, C:\Tomcat\bin или что-то совсем другое, но не C:\Tomcat\webapps\contextname или что бы вы ни ожидали. В обычном проекте Eclipse это было бы C:\Eclipse\workspace\projectname, Вы можете узнать о текущем рабочем каталоге следующим образом:

System.out.println(new File(".").getAbsolutePath());

Однако рабочий каталог никоим образом не является программно управляемым. Вы действительно должны использовать абсолютные пути в File API вместо относительных путей. Например C:\full\path\to\file.ext,

Вы не хотите жестко кодировать или угадывать абсолютный путь в Java (веб) приложениях. Это только проблема переносимости (то есть она работает в системе X, но не в системе Y). Обычной практикой является размещение таких ресурсов в пути к классам или добавление полного пути к пути к классам (в IDE, такой как Eclipse, это src папка и "путь сборки" соответственно). Таким образом, вы можете получить их с помощью ClassLoader от ClassLoader#getResource() или же ClassLoader#getResourceAsStream(), Как вы выяснили, он может найти файлы относительно "корня" пути к классам. В веб-приложениях (или любых других приложениях, использующих несколько загрузчиков классов) рекомендуется использовать ClassLoader как возвращено Thread.currentThread().getContextClassLoader() для этого, так что вы можете посмотреть "за пределами" контекста веб-приложения.

Другой альтернативой в веб-приложениях является ServletContext#getResource() и его коллега ServletContext#getResourceAsStream(), Он может получить доступ к файлам, расположенным в общественных web папка проекта webapp, включая /WEB-INF папка. ServletContext доступно в сервлетах по наследству getServletContext() метод, вы можете назвать его как есть.

Смотрите также:

getResourceAsStream это правильный способ сделать это для веб-приложений (как вы уже узнали).

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

FileInputStream загрузит путь к файлу, который вы передаете конструктору, относительно рабочего каталога процесса Java. Обычно в веб-контейнере это что-то вроде bin папка.

getResourceAsStream() загрузит путь к файлу относительно пути к классу вашего приложения.

FileInputStream Класс работает напрямую с базовой файловой системой. Если рассматриваемый файл не присутствует там физически, он не сможет открыть его. getResourceAsStream() Метод работает по-другому. Он пытается найти и загрузить ресурс, используя ClassLoader класса это называется. Это позволяет ему находить, например, ресурсы, встроенные в jar файлы.

classname.getResourceAsStream() загружает файл через загрузчик классов с именем класса. Если класс пришел из jar-файла, именно из него будет загружен ресурс.

FileInputStream используется для чтения файла из файловой системы.

Я здесь, разделяя оба использования, помечая их как "Чтение файла" (java.io) и "Чтение ресурса" (ClassLoader.getResourceAsStream()).

Чтение файла - 1. Работает в локальной файловой системе. 2. Пытается найти файл, запрошенный из текущей запущенной директории JVM, как root 3. Идеально подходит для использования файлов для обработки в заранее определенном месте, например,/dev/files или C: \ Data.

Resource Read -1. Работает с путем к классу 2. Пытается найти файл / ресурс в текущем или родительском пути к загрузчику классов. 3. Идеально подходит для загрузки файлов из упакованных файлов, таких как war или jar.

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