- Java – Read a file from resources folder
- 1. Files in resources folder
- 2. Get a file from the resources folder.
- 3. Get a file from the resources folder – Unit Test
- 4. Get all files from a resource folder. (NON-JAR environment)
- 5. Get all files from a resource folder. (JAR version)
- Download Source Code
- References
- Comments
- Java – Чтение файла из папка ресурсов
- 1. Файлы в ресурсах папка
- 2. Получите файл из папки ресурсов.
- 3. Получите файл из папки ресурсов – Модульный тест
- 4. Получите все файлы из папки ресурсов. (Среда, ОТЛИЧНАЯ от JAR)
- 5. Получите все файлы из папки ресурсов. (Версия JAR)
- Как устроен билд APK файла внутри
- Процесс создания APK и компиляции кода
- Рассматриваемые темы
- Архитектура процессоров и зачем нужна виртуальная машина
- Понимание Java виртуальной машины
- Андроид виртуальная машина
- Комплияция в .dex файл
- ART против Dalvik
- Каждый этап описанного процесса
- Source Code (Исходный код)
- Resource Files
- AIDL Files
- Library Modules
- AAR Libraries
- JAR Libraries
- Android Asset Packaging Tool
- resources.arsc
- D8 и R8
- Dex and Multidex
Java – Read a file from resources folder
By mkyong | Last updated: September 4, 2020
Viewed: 1,546,378 (+4,744 pv/w)
In Java, we can use getResourceAsStream or getResource to read a file or multiple files from a resources folder or root of the classpath.
The getResourceAsStream method returns an InputStream .
The getResource method returns an URL and normally convert it to a File ; Not working in JAR file.
1. Files in resources folder
1.1 Review the files in the src/main/resources , later we will access the files and print out the file content.
1.2 By default, build tools like Maven, Gradle, or common Java practice will copy all files from src/main/resources to the root of target/classes or build/classes . So, when we try to read a file from src/main/resources , we read the file from the root of the project classpath.
1.3 Below is a JAR file structure. Usually, the files in the resources folder will copy to the root of the classpath.
2. Get a file from the resources folder.
2.1 The below example demonstrates the use of getResourceAsStream and getResource methods to read a file json/file1.json from the resources folder and print out the file content.
Note
- The getResource method is not working in the JAR file.
- The getResourceAsStream method works everywhere.
2.2 Now, we pack the project into a JAR file and run it; this time, the getResource will fail and returns either NoSuchFileException or InvalidPathException . We cannot read the files inside the JAR file via the resource URL.
Run the JAR file on Linux (Ubuntu), it throws NoSuchFileException .
Run the JAR file on Windows, it throws InvalidPathException .
P.S This example uses the Maven plugin maven-jar-plugin to create the JAR file.
3. Get a file from the resources folder – Unit Test
3.1 We put the test resources at folder src/test/resources for unit tests. Usually, the files in test resources will copy to the target/test-classes folder.
3.2 It works the same way we read the file from src/main/resources . We use the same getResourceAsStream and getResource methods to read the file from the src/test/resources .
4. Get all files from a resource folder. (NON-JAR environment)
If we don’t know the exact filename and want to read all files, including sub-folder files from a resources folder, we can use the NIO Files.walk to easily access and read the files.
4.1 The below example uses Files.walk to read all files from a folder src/main/resources/json :
4.2 However, the standard Files.walk in example 4.1 can’t access the files in the JAR file directly, try run the example 4.1 in a JAR environment, and it throws FileSystemNotFoundException .
5. Get all files from a resource folder. (JAR version)
5.1 This example shows how to Files.walk a folder inside a JAR file via FileSystems and URI jar:file:xxx.jar .
- File walks the folder inside a JAR file using FileSystems , and get all the filename, see getPathsFromResourceJAR()
- Loop all the filename, access and print each file like example 2.1, see getFileFromResourceAsStream() .
Download Source Code
References
mkyong
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.
Comments
How about reading al files under a resources directory like this?
src/main/resources
+ file1.txt
+ file2.txt
…
+ file9.txt
We updated the article, see example 4 and 5. Files.walk is your best friend.
And still, examples 4 and 5 shows how to access files in subfolder of resource folder, but not in resource folder itself.
Hi mkyong.This work fine ide but not work jar?
Can you help we ?
We updated the example to access the files inside the JAR file, the answer is getResourceAsStream .
The getResource is not working in JAR file.
The getResourceAsStream works everywhere.
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(“fileName”);
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer);
query = writer.toString();
i am added Apache commons in mvn pom.xml then what is the query means
^ Thanks a lot man!
new File(classLoader.getResource(fileName).getFile());This won’t work with files if they have whitespaces or special characters (e.g. #) in their paths. Rather use
Thanks, we updated the example with toURI()
toURI() does not work in jar and gives a error: URI is not hierarchical
Thanks to MyKong and you I got it working!
There is also one that I like the most:
File file = ResourceUtils.getFile(“classpath:file/test.txt”)
String txt= FileUtils.readFileToString(file);
ResourceUtils are in spring and FileUtils are in commons io.
OMG, many thanks for this ^^
Thanks for sharing this – ResourceUtils
I’m working on an app which uses a 3rd party library with an API expecting a java.io.File .
The data to be passed “as a file” I could create dynamically or get from a resource.
I could get the resource as a File with the class loader getResource method. But you already made the point: that will not work with a Jar.
The only solution so far (independently if I create the data on the fly or get it (as Stream) from a resource) is to store that data in a temporal file and give it to the API.
Is there a way to avoid the temporal file? Can we make a File object for something in memory?
Источник
Java – Чтение файла из папка ресурсов
В этой статье будет показано, как прочитать файл из папки “ресурсы”, “getResourceAsStream” или “getResource”.
Автор: mkyong
Дата записи
Автор оригинала: mkyong.
В Java мы можем использовать getResourceAsStream или getResource для чтения файла или нескольких файлов из папки ресурсы или корневого каталога пути к классу.
Метод getResourceAsStream возвращает Входной поток .
Метод getResource возвращает URL и обычно преобразует его в Файл ; Не работает в файле JAR .
1. Файлы в ресурсах папка
1.1 Просмотрите файлы в src/main/ресурсы , позже мы получим доступ к файлам и распечатаем содержимое файла.
1.2 По умолчанию инструменты сборки, такие как Maven, Gradle или обычная практика Java, будут копировать все файлы из src/основные/ресурсы в корневой каталог целевые/классы или сборка/классы . Итак, когда мы пытаемся прочитать файл из src/main/ресурсы , мы читаем файл из корневого каталога пути к классам проекта.
1.3 Ниже приведена структура файла JAR. Обычно файлы в папке ресурсы копируются в корневой каталог пути к классу.
2. Получите файл из папки ресурсов.
2.1 Приведенный ниже пример демонстрирует использование getResourceAsStream и getResource методы чтения файла json/файл 1.json из папки ресурсы
- Метод getResource не работает в файле JAR.
- Метод getResourceAsStream работает везде.
2.2 Теперь мы упаковываем проект в файл JAR и запускаем его; на этот раз getResource завершится ошибкой и вернет либо Исключение NoSuchFileException , либо Исключение InvalidPathException . Мы не можем прочитать файлы внутри файла JAR по URL-адресу ресурса.
Запустите файл JAR в Linux (Ubuntu), он вызовет Исключение NoSuchFileException .
Запустите файл JAR в Windows, он вызовет Исключение InvalidPathException .
P.S В этом примере используется плагин Maven maven-jar-плагин чтобы создать файл JAR.
3. Получите файл из папки ресурсов – Модульный тест
3.1 Мы помещаем тестовые ресурсы в папку src/test/ресурсы для модульных тестов. Обычно файлы в тестовых ресурсах копируются в папку target/test-classes .
3.2 Это работает так же, как мы читаем файл из src/main/ресурсы . Мы используем то же самое getResourceAsStream и getResource методы чтения файла из src/test/ресурсов .
4. Получите все файлы из папки ресурсов. (Среда, ОТЛИЧНАЯ от JAR)
Если мы не знаем точного имени файла и хотим прочитать все файлы, включая файлы вложенных папок из папки ресурсов, мы можем использовать NIO Файлы.перейдите , чтобы легко получить доступ к файлам и прочитать их.
4.1 В приведенном ниже примере используются Файлы.пройдите чтобы прочитать все файлы из папки src/основные/ресурсы/json :
4.2 Однако стандартные Файлы.прогулка в примере 4.1 не удается получить доступ к файлам в файле JAR напрямую, попробуйте запустить пример 4.1 в среде JAR, и он выдает Исключение FileSystemNotFoundException .
5. Получите все файлы из папки ресурсов. (Версия JAR)
5.1 В этом примере показано, как Файлы.перейдите в папку внутри файла JAR через Файловые системы и URI jar:файл: xxx.jar .
Идея в том, чтобы:
- Файл перемещает папку внутри файла JAR, используя Файловые системы , и получает все имена файлов, см. получение путей из JAR ресурсов()
- Зациклите все имена файлов, получите доступ и распечатайте каждый файл, как в примере 2.1, см. получение файла из ResourceAsStream() .
Источник
Как устроен билд APK файла внутри
Процесс создания APK и компиляции кода
Рассматриваемые темы
- Архитектура процессоров и необходимость для виртуальной машины
- Понимание Java виртуальной машины
- Компиляция исходного кода
- Виртуальная машина Андроид
- Процесс компиляции в .dex файл
- ART против Dalvik
- Описание каждой части билд процесса
- Исходный код
- Файлы ресурсов
- AIDL файлы
- Модули библиотек
- AAR библиотеки
- JAR библиотеки
- Android Asset Packaging Tool
- resources.arsc
- D8 и R8
- Dex и Multidex
- Подписывание APK файла
- Ссылки
Понимание флоу процесса билда APK файла, среда исполнения и компиляция кода
Этот пост нацелен быть отправной точкой для разработчиков, чтобы они ближе познакомились с билд процессом и созданием APK файла.
Архитектура процессоров и зачем нужна виртуальная машина
Андроид после того как вышел в 2007 году претерпел множество изменений связанный с билд процессом, средой исполнения и улучшениями производительности.
У андроида много удивительных характеристик и одна из них разные архитектуры процессоров такие как ARM64 и x86
Невозможно скомпилировать код, который поддерживает каждую архитектуру. Вот именно поэтому используется Java виртуальная машина.
Понимание Java виртуальной машины
JVM это виртуальная машина, позволяющая устройству запускать код, который скомпилирован в Java байткод
Используя JVM, вы избавляетесь от проблемы с разной архитектурой процессоров.
JVM предоставляет переносимость и она позволяет запускать Java код в виртуальной среде, вместо того, чтобы запускать его сразу «на железе»
Но JVM была создана для систем с большими мощностями по ресурсам, а наш андроид имеет сравнительно мало памяти и заряда батареи.
По этой причине Google создал адаптированную под андроид виртуальную машину, которая называется Dalvik.
Компилируем исходный код
Наш исходный Java код для андроида компилируется в класс файл .class с байткодом с помощью javac компилятора и запускается на JVM
Для котлина есть kotlinc компилятор, который делает совместимый с Java байткод.
Байткод — это набор инструкций, который выполняется на целевом устройстве.
Java байткод — это набор инструкций для Java виртуальной машины.
Андроид виртуальная машина
Каждое андроид приложение работает на своей виртуальной машине. С версий 1.0 до 4.4, это был Dalvik. В андроид 4.4, вместе с Dalvik, Google представил в качестве эксперимента новый андроид runtime, который назывался ART
Сгенерированный класс файл .class содержит JVM Java байткод.
Но у андроида есть свой собственный оптимизированный формат байткода, который называется Dalvik bytecode — это просто инструкции машинного кода для процессора также как и JVM байткод.
Комплияция в .dex файл
Во время компиляции происходит конвертация .class класс файл и .jar библиотеки в один classes.dex файл, который содержит Dalvik байткод.
Команда dx превращает все .class и .jar файлы в один classes.dex файл, который написан с форматом Dalvik байткода.
Dex — это аббревиатура с английского — Dalvik Executable.
ART против Dalvik
C версии 4.4 андроид мигрировал на ART. ART также работает с .dex файлом.
Преимущество ART над Dalvik проявляется в том, что приложения запускаются быстрее, потому что весь DEX байткод транслируется в машинный код во время установки, не нужно дополнительного времени на компиляцию в рантайме.
ART и Dalvik совместимы, так что приложения разработанные для Dalvik должны работать и на ART.
Компиляция Dalvik (JIT- just in time) имела такие минусы как — быстрая трата батареи, лаги в приложениях и плохой перформанс. В Dalvik трансляция происходит только когда это нужно. Мы открываем новый экран и только в этот момент происходит трансляция, за счет этого установка происходит быстрее, но при этом проседает перформанс.
Это причина по которой Google сделал Android Runtime (ART).
ART — основан на AOT (ahead of time) компиляции, она происходит до того как приложение запустится.
В ART компиляция происходит во время установки приложения. Это ведет к более долгому времени установки, но уменьшает трату батареи и избавляет от лагов, которые были на Dalvik.
Несмотря на то, что Dalvik был заменен на ART, .dex формат файлов еще используется
В андроид 7.0 JIT вернулся. Гибридная среда сочетает фичи как от JIT компиляции так и
от ART
Среда запуска байткода это очень важная часть андроида и она вовлечена в процесс запуска и установки приложения
Каждый этап описанного процесса
Source Code (Исходный код)
Это Java и Kotlin файлы в src пакете.
Resource Files
Файлы находящиеся в директории с ресурсами
AIDL Files
AIDL — аббревиатура Android Interface Definition Language, позволяет вам описать интерфейс межпроцессорного взаимодействия.
AIDL — может использоваться между любыми процессами в андроиде.
Library Modules
Модули библиотек содержат Java или Kotlin классы, компоненты андроида и ресурсы.
Код и ресурсы бибилотеки компилируются и пакуются вместе с приложением.
Поэтому модуль библиотеки может считаться компайл тайм артефактом.
AAR Libraries
Андроид библиотеки компилируются в AAR — android archive файл, который вы можете использовать как зависимость для вашего android app модуля.
AAR файлы могут содержать андроид ресурсы и файл манифеста, что позволяет вам упаковать туда общие ресурсы такие как layouts и drawables в дополнение к Java или Kotlin классам и методам.
JAR Libraries
JAR это Java библиотека и в отличие от AAR она не может содержать андроид ресурсы и манифесты.
Android Asset Packaging Tool
AAPT2 — аббревиатура (Android Asset Packaging Tool) — компилирует манифест и файлы ресурсов в один APK.
Этот процесс разделен на два шага компиляцию и линковку Это улучшает производительность так как если вы поменяете один файл, вам нужно компилировать только его и прилинковать к остальным файлам командой ‘link’
AAPT2 может компилировать все типы андроид ресурсов, таких как drawables и XML файлы.
При вызове AAPT2 для компиляции, туда передается по одному ресурсному файлу на каждый вызов
Затем APPT2 парсит файл и генерирует промежуточный бинарный файл с расширением .flat
Фаза линковки склеивает все промежуточные файлы сгенерированные в фазе компиляции и дает нам на выход один .apk файл. Вы также можете сгенерировать R.java файл и правила для proguard в это же время.
resources.arsc
Полученный на выходе .apk файл не включает в себя DEX файл, APK не подписан и не может быть запущен на устройстве.
APK содержит AndroidManifest, бинарные XML файлы и resources.arsc
resource.arsc содержит всю мета информацию о ресурсах, такую как индексы всех ресурсов в пакете
Это бинарный файл и APK который может быть запущен. APK который вы обычно создаете и запускаете не сжат и может быть использован просто посредством размещения в памяти.
R.java файл это выходной файл вместе с APK ему назначен уникальный id, который позволяет Java коду использовать ресурсы во время компиляции.
arsc это индекс ресурса который используется во время запуска приложения
D8 и R8
Начиная с андроид студии 3.1 и далее, D8 был сделан дефолтным компилятором.
D8 производит более маленькие dex файлы с лучшей производительностью, если сравнивать со старым dx.
R8 используется для компиляции кода. R8 это оптимизированная версия D8
D8 играет роль конвертера класс файлов в Dex файлы, а также производит дешугаринг функций из Java 8 в байткод, который может быть запущен на андроиде
R8 оптимизирует dex байткод. Он предоставляет такие фичи как оптимизация, обфускация, удаление ненужных классов.
Обфускация уменьшает размер вашего приложения укорачивая названия классов, методов и полей.
Обфускация имеет и другие преимущества для предотвращения реверс инжиниринга, но основная цель уменьшить размер.
Оптимизация уменьшает размер Dex файла путем переписывания ненужных частей кода и инлайнинга.
С помощью дешугаринга мы можем использовать удобные фичи языка Java 8 на андроиде.
Dex and Multidex
R8 дает на выходе один DEX файл, который называется classes.dex
Если количество методов приложения переваливает за 65,536, включая подключенные библиотеки, то произойдет ошибка при билде
Источник