Android jar with resources

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, включая подключенные библиотеки, то произойдет ошибка при билде

Источник

Оцените статью