java FileInputStream — различия в зависимости от того, как ссылается на объект File:загрузчик классов/файловая система
-
19-09-2019 - |
Вопрос
я использую Apache POI чтобы извлечь некоторые данные из файла Excel.
Мне нужен InputStream для создания экземпляра класса POI HSSFWorkbook. HSSFWorkbook wb = new HSSFWorkbook(inputStreamX);
Я нахожу различия, если пытаюсь создать объект InputStream, например
InputStream inputStream = new FileInputStream(new File("/home/xxx/workspace/myproject/test/resources/importTest.xls"));
InputStream inputStream2 = new FileInputStream(getClass().getResource("/importTest.xls").getFile());
InputStream inputStream3 = new ClassPathResource("importTest.xls").getInputStream();
Если я создаю объект POI с помощью inputStream, он работает нормально.
Но inputStream2 и inputStream3 выдают это исключение
java.io.IOException: Invalid header signature; read -2300849302551019537, expected -2226271756974174256
at org.apache.poi.poifs.storage.HeaderBlockReader.<init>(HeaderBlockReader.java:100)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:84)
Похоже, что заголовок двоичного файла отличается, и библиотека не может распознать его как файл Excel.Я не могу понять, почему.
Единственная разница, которую я вижу, заключается в том, что inputStream2 и 3 используют загрузчик классов для поиска файла.(КлассПатРесаурс это класс Spring).
Я хотел бы, чтобы путь к файлу был отделен от системы.Поэтому я бы предпочел что-то вроде inputStream2 или 3.
Есть ли у вас какие-либо идеи о том, почему это происходит?
Спасибо
Обновлять:
Я попытался записать на диск inputStream и inputStream2.
Файл Excel, поставляемый с inputStream, в порядке.inputStream2 содержит файл Excel с некоторыми странными символами, которые оборачивают реальный контент.
Кажется, что maven каким-то образом повреждает файл Excel во время сборки.
Так что это в основном файл, который я получаю с помощью classLoader (под /home/xxx/workspace/myproject/target/test-classes/importTest.xls
) это не ок.
Есть идеи?
Решение
Проблема кажется знатоком фильтрация вариант.
Если помпон выглядит вот так
<testResource>
<directory>${basedir}/src/test/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.sql</include>
<include>**/*.xls</include>
</includes>
<filtering>true</filtering>
</testResource>
Если для параметра фильтрации установлено значение true для файлов xls, они повреждаются.
Другие советы
Попытался ли ты ClassLoader#getResourceAsStream(String)
?Вероятно, он будет вести себя так же, как и ваша вторая попытка, используя Class#getResource(String)
, как указано в документации последнего.
Моя первая мысль заключалась в том, что такой файл не найден, но если он постоянно читает одно и то же значение (-2300849302551019537
) каждый раз, когда вы запускаете программу, это означает, что там действительно есть файл, который читается.Перехватите оператор после инициализации вашего InputStream
и проверьте экземпляр потока в отладчике.Вы сможете найти ссылку на имя основного файла.Чтобы сделать это проще, попробуйте использовать ClassLoader#getResources(String)
и проверьте последовательность возвращаемых URL-адресов.