Различные способы загрузить файл как InputStream

В первом случае вы выполняете in.read() вне цикла. Во втором случае вы получаете in.read() внутри выполнения цикла.

Помните, что условие цикла вычисляется на каждой итерации, поэтому вы выполняете doinb in.read на каждой итерации.

Может быть, вы хотели это сделать

for(int t=0,tests=<Integer.parseInt(in.readLine());t<tests;t++) {body}

?

210
задан Buhake Sindi 2 February 2012 в 01:13
поделиться

2 ответа

Существуют тонкие различия относительно как fileName Вы являетесь передающими, интерпретируется. В основном у Вас есть 2 различных метода: ClassLoader.getResourceAsStream() и Class.getResourceAsStream(). Эти два метода определят местоположение ресурса по-другому.

В Class.getResourceAsStream(path), путь интерпретируется как путь, локальный для пакета класса, от которого Вы называете его. Например, вызов, String.getResourceAsStream("myfile.txt") будет искать файл в Вашем пути к классу в следующем местоположении: "java/lang/myfile.txt". Если Ваш путь запускается с a /, затем это будет считаться полным путем и начнет искать от корня пути к классу. Так вызов String.getResourceAsStream("/myfile.txt") посмотрит на следующее местоположение в Вашем пути к классу ./myfile.txt.

ClassLoader.getResourceAsStream(path) будет полагать, что все пути полные пути. Так вызов String.getClassLoader().getResourceAsStream("myfile.txt") и String.getClassLoader().getResourceAsStream("/myfile.txt") будет оба искать файл в Вашем пути к классу в следующем местоположении: ./myfile.txt.

Каждый раз я упоминаю местоположение в этом сообщении, это могло быть местоположение в Вашей файловой системе самой, или в соответствующем файле банки, в зависимости от Класса и/или ClassLoder, из которого Вы загружаете ресурс.

В Вашем случае Вы загружаете класс из Сервера приложений, таким образом, Ваш должен использовать Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName) вместо this.getClass().getClassLoader().getResourceAsStream(fileName). this.getClass().getResourceAsStream() будет также работать.

Прочитайте эту статью для более подробной информации о той конкретной проблеме.


Предупреждение для пользователей Tomcat 7 и ниже

Один из ответов на этот вопрос указывает, что мое объяснение, кажется, является неправильным для Tomcat 7. Я попытался озираться для наблюдения, почему это имело бы место.

Таким образом, я посмотрел на исходный код Tomcat WebAppClassLoader для нескольких версий Tomcat. Реализация findResource(String name) (который является utimately ответственный за создание URL к требуемому ресурсу), фактически идентично в Tomcat 6 и Tomcat 7, но отличается в Tomcat 8.

В версиях 6 и 7 реализация не пытается нормализовать имя ресурса. Это означает это в этих версиях, classLoader.getResourceAsStream("/resource.txt") может не привести к тому же результату как classLoader.getResourceAsStream("resource.txt") событие, хотя это должно (так как это, что Javadoc указывает). [исходный код]

В версии 8, хотя, имя ресурса нормализовано, чтобы гарантировать, что абсолютная версия имени ресурса является той, которая используется. Поэтому в Tomcat 8, два вызова, описанные выше, должны всегда возвращать тот же результат. [исходный код]

В результате необходимо быть дополнительны осторожный при использовании ClassLoader.getResourceAsStream() или Class.getResourceAsStream() на версиях Tomcat ранее, чем 8. И необходимо также иметь в виду это class.getResourceAsStream("/resource.txt") на самом деле вызовы classLoader.getResourceAsStream("resource.txt") (продвижение / разделяется).

285
ответ дан LordOfThePigs 23 November 2019 в 04:36
поделиться

Использовать MyClass.class.getClassLoader().getResourceAsStream(path) загрузить ресурс, связанный с Вашим кодом. Использовать MyClass.class.getResourceAsStream(path) поскольку ярлык, и для ресурсов упаковывается в пакете Вашего класса.

Использовать Thread.currentThread().getContextClassLoader().getResourceAsStream(path) получить ресурсы, которые являются частью клиентского кода, не плотно, ограничивает к коду вызова. Необходимо быть осторожными с этим, поскольку загрузчик класса контекста потока мог указывать на что-либо.

20
ответ дан Tom Hawtin - tackline 23 November 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: