Как читать текстовый файл из classpath в Java
Я пытаюсь прочитать текстовый файл, который установлен в системной переменной CLASSPATH. Не пользовательская переменная.
Я пытаюсь получить входной поток в файл, как показано ниже:
Поместите каталог файла (D:\myDir
) в CLASSPATH и попробуйте ниже:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt");
Поместите полный путь к файлу (D:\myDir\SomeTextFile.txt
) в CLASSPATH и попробуйте те же 3 строки кода.
Но, к сожалению, NONE из них работает, и я всегда получаю null
в свой InputStream in
.
Ответы
Ответ 1
С каталогом в пути к классам, из класса, загруженного одним и тем же загрузчиком классов, вы можете использовать любой из следующих:
// From ClassLoader, all paths are "absolute" already - there no context
// from which they could be relative. Therefore you don't need a leading slash.
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
// From Class, the path is relative to the package of the class unless
// you include a leading slash, so if you don't want to use the current
// package, include a slash like this:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
Если они не работают, это говорит о том, что что-то еще не так.
Итак, например, возьмите этот код:
package dummy;
import java.io.*;
public class Test
{
public static void main(String[] args)
{
InputStream stream = Test.class.getResourceAsStream("/SomeTextFile.txt");
System.out.println(stream != null);
stream = Test.class.getClassLoader().getResourceAsStream("SomeTextFile.txt");
System.out.println(stream != null);
}
}
И эта структура каталогов:
code
dummy
Test.class
txt
SomeTextFile.txt
И затем (используя разделитель пути Unix, когда я нахожусь в ящике Linux):
java -classpath code:txt dummy.Test
Результаты:
true
true
Ответ 2
При использовании Spring Framework (либо в виде набора утилит , либо) - вам не нужно для использования последней функциональности) вы можете легко использовать абстракцию Ресурса.
Resource resource = new ClassPathResource("com/example/Foo.class");
Через интерфейс Resource вы можете получить доступ к ресурсу как InputStream, URL, URI или File. Изменение типа ресурса, например. ресурс файловой системы - это просто вопрос об изменении экземпляра.
Ответ 3
Вот как я читал все строки текстового файла в моем пути к классам, используя Java 7 NIO:
...
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
...
Files.readAllLines(
Paths.get(this.getClass().getResource("res.txt").toURI()), Charset.defaultCharset());
NB это пример того, как это можно сделать. Вам придётся внести необходимые улучшения. Этот пример будет работать только в том случае, если файл действительно присутствует в вашем пути к классам, иначе будет выведено исключение NullPointerException, когда getResource() возвращает null, и на него вызывается .toURI().
Кроме того, поскольку Java 7, одним удобным способом задания наборов символов является использование констант, определенных в java.nio.charset.StandardCharsets
(они, согласно их javadocs, "гарантированно будут доступны для каждой реализации платформы Java".).
Следовательно, если вы знаете, что кодировка файла является UTF-8, тогда явно укажите charset StandardCharsets.UTF_8
Ответ 4
Попробуйте
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
Ваши попытки не сработали, потому что только загрузчик классов для ваших классов может загружаться из пути к классам. Вы использовали загрузчик классов для самой java-системы.
Ответ 5
Чтобы действительно прочитать содержимое файла, мне нравится использовать Commons IO + Spring Core. Предполагая, что Java 8:
try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) {
IOUtils.toString(stream);
}
В качестве альтернативы:
InputStream stream = null;
try {
stream = new ClassPathResource("/log4j.xml").getInputStream();
IOUtils.toString(stream);
} finally {
IOUtils.closeQuietly(stream);
}
Ответ 6
Чтобы получить абсолютный путь класса, попробуйте следующее:
String url = this.getClass().getResource("").getPath();
Ответ 7
Как-то лучший ответ для меня не работает. Мне нужно использовать немного другой код.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("SomeTextFile.txt");
Я надеюсь, что это поможет тем, кто сталкивается с той же проблемой.
Ответ 8
Если вы используете Guava:
import com.google.common.io.Resources;
мы можем получить URL-адрес от CLASSPATH:
URL resource = Resources.getResource("test.txt");
String file = resource.getFile(); // get file path
или InputStream:
InputStream is = Resources.getResource("test.txt").openStream();
Ответ 9
Чтобы прочитать содержимое файла в String из classpath
, вы можете использовать это:
private String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath))
{
return IOUtils.toString(inputStream);
}
}
Примечание:
IOUtils
является частью Commons IO
.
Назовите его следующим образом:
String fileContents = resourceToString("ImOnTheClasspath.txt");
Ответ 10
Вы говорите: "Я пытаюсь прочитать текстовый файл, который установлен в системной переменной CLASSPATH". Я предполагаю, что это в Windows, и вы используете это уродливое диалоговое окно для редактирования "Системных переменных".
Теперь вы запускаете свою программу Java в консоли. И это не работает: консоль получает копию значений системных переменных один раз при запуске. Это означает, что любое изменение в диалоговом окне впоследствии не имеет никакого эффекта.
Существуют следующие решения:
-
Запустите новую консоль после каждого изменения
-
Используйте set CLASSPATH=...
в консоли, чтобы установить копию переменной в консоли и когда ваш код работает, вставьте последнее значение в диалог переменных.
-
Поместите вызов Java в файл .BAT
и дважды щелкните его. Это создаст новую консоль каждый раз (таким образом, копируя текущее значение системной переменной).
BEWARE: Если у вас также есть пользовательская переменная CLASSPATH
, она затеняет вашу системную переменную. Поэтому обычно лучше поместить вызов вашей Java-программы в файл .BAT
и установить там путь к классу (используя set CLASSPATH=
), а не полагаться на глобальную системную или пользовательскую переменную.
Это также гарантирует, что у вас может быть более одной Java-программы, работающей на вашем компьютере, потому что у них есть разные пути к классам.
Ответ 11
Всякий раз, когда вы добавляете каталог в путь к классам, все ресурсы, определенные в нем, будут скопированы непосредственно в папку развертывания приложения (например, bin).
Чтобы получить доступ к ресурсу из вашего приложения, вы можете использовать префикс "/", который указывает на корневой путь в папке развертывания, остальные части пути зависят от местоположения вашего ресурса (независимо от того, D:\myDir "или вложенный под подпапкой)
Подробнее см. учебник.
В вашем примере вы должны иметь доступ к своему ресурсу через следующее:
InputStream is = getClass().getResourceAsStream("/SomeTextFile.txt");
Зная, что "SomeTextFile.txt" существует непосредственно под "D:\myDir"
Ответ 12
Мой ответ не совсем то, что задают в вопросе. Скорее я даю решение, как легко мы можем прочитать файл в наше Java-приложение из пути к классам нашего проекта.
Например, предположим, что имя файла конфигурации example.xml находится по следующему пути: -
com.myproject.config.dev
и наш исполняемый файл класса Java находится по следующему пути: -
com.myproject.server.main
Теперь просто проверьте оба указанных выше пути, которые являются ближайшим общим каталогом/папкой, откуда вы можете получить доступ как к dev, так и главной папке/папке (com.myproject.server.main - где существует исполняемый класс java для наших приложений) - мы видим, что это папка/каталог myproject, которая является ближайшей общей папкой/папкой, из которой мы можем получить доступ к нашему файлу example.xml. Поэтому из исполняемого класса java, находящегося в папке/каталоге main, мы должны вернуться на два шага, например ../../, чтобы получить доступ к myproject. Теперь, следуя этому, посмотрим, как мы можем прочитать файл: -
package com.myproject.server.main;
class Example {
File xmlFile;
public Example(){
String filePath = this.getClass().getResource("../../config/dev/example.xml").getPath();
this.xmlFile = new File(filePath);
}
public File getXMLFile() {
return this.xmlFile;
}
public static void main(String args[]){
Example ex = new Example();
File xmlFile = ex.getXMLFile();
}
}
Ответ 13
Я использую сервер приложений webshpere, и мой веб-модуль построен на Spring MVC. Test.properties
были расположены в папке ресурсов, я попытался загрузить эти файлы, используя следующее:
-
this.getClass().getClassLoader().getResourceAsStream("Test.properties");
-
this.getClass().getResourceAsStream("/Test.properties");
Ни один из приведенных выше кодов не загрузил файл.
Но с помощью приведенного ниже кода файл свойств был успешно загружен:
Thread.currentThread().getContextClassLoader().getResourceAsStream("Test.properties");
Благодаря пользователю "user1695166".
Ответ 14
Используйте org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));
Ответ 15
Сценарий:
1) client-service-1.0-SNAPSHOT.jar
имеет зависимость read-classpath-resource-1.0-SNAPSHOT.jar
2) мы хотим прочитать содержимое ресурсов пути класса (sample.txt
) read-classpath-resource-1.0-SNAPSHOT.jar
через client-service-1.0-SNAPSHOT.jar
.
3) read-classpath-resource-1.0-SNAPSHOT.jar
имеет src/main/resources/sample.txt
Вот пример рабочего кода, который я подготовил, после 2-3 дней, тратя время на разработку, я нашел полное сквозное решение, надеюсь, что это поможет сэкономить ваше время
1. pom.xml
of read-classpath-resource-1.0-SNAPSHOT.jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jar-classpath-resource</groupId>
<artifactId>read-classpath-resource</artifactId>
<version>1.0-SNAPSHOT</version>
<name>classpath-test</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.version>4.3.3.RELEASE</org.springframework.version>
<mvn.release.plugin>2.5.1</mvn.release.plugin>
<output.path>${project.artifactId}</output.path>
<io.dropwizard.version>1.0.3</io.dropwizard.version>
<commons-io.verion>2.4</commons-io.verion>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.verion}</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>${mvn.release.plugin}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>demo.read.classpath.resources.ClassPathResourceReadTest</mainClass>
</manifest>
<manifestEntries>
<Implementation-Artifact-Id>${project.artifactId}</Implementation-Artifact-Id>
<Class-Path>sample.txt</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>demo.read.classpath.resources.ClassPathResourceReadTest</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2. ClassPathResourceReadTest.java
класс в read-classpath-resource-1.0-SNAPSHOT.jar
, который загружает содержимое файла ресурсов пути к классу.
package demo.read.classpath.resources;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public final class ClassPathResourceReadTest {
public ClassPathResourceReadTest() throws IOException {
InputStream inputStream = getClass().getResourceAsStream("/sample.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
List<Object> list = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
list.add(line);
}
for (Object s1: list) {
System.out.println("@@@ " +s1);
}
System.out.println("getClass().getResourceAsStream('/sample.txt') lines: "+list.size());
}
}
3. pom.xml
of client-service-1.0-SNAPSHOT.jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>client-service</groupId>
<artifactId>client-service</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>jar-classpath-resource</groupId>
<artifactId>read-classpath-resource</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<useUniqueVersions>false</useUniqueVersions>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<mainClass>com.crazy.issue.client.AccessClassPathResource</mainClass>
</manifest>
<manifestEntries>
<Implementation-Artifact-Id>${project.artifactId}</Implementation-Artifact-Id>
<Implementation-Source-SHA>${buildNumber}</Implementation-Source-SHA>
<Class-Path>sample.txt</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.2</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.crazy.issue.client.AccessClassPathResource</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
4. AccessClassPathResource.java
создать экземпляр ClassPathResourceReadTest.java
class, где он загрузит sample.txt
и также распечатает его содержимое.
package com.crazy.issue.client;
import demo.read.classpath.resources.ClassPathResourceReadTest;
import java.io.IOException;
public class AccessClassPathResource {
public static void main(String[] args) throws IOException {
ClassPathResourceReadTest test = new ClassPathResourceReadTest();
}
}
5.Run Исполняемая банка следующая:
[[email protected] lib]$ java -jar client-service-1.0-SNAPSHOT.jar
****************************************
I am in resources directory of read-classpath-resource-1.0-SNAPSHOT.jar
****************************************
3) getClass().getResourceAsStream('/sample.txt'): 3
Ответ 16
Не используйте метод getClassLoader() и используйте "/" перед именем файла. "/" очень важно
this.getClass().getResourceAsStream("/SomeTextFile.txt");
Ответ 17
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile
{
/**
* * feel free to make any modification I have have been here so I feel you
* * * @param args * @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// thread pool of 10
File dir = new File(".");
// read file from same directory as source //
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
// if you wanna read file name with txt files
if (file.getName().contains("txt")) {
System.out.println(file.getName());
}
// if you want to open text file and read each line then
if (file.getName().contains("txt")) {
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(
file.getAbsolutePath());
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(
fileReader);
String line;
// get file details and get info you need.
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
// here you can say...
// System.out.println(line.substring(0, 10)); this
// prints from 0 to 10 indext
}
} catch (FileNotFoundException ex) {
System.out.println("Unable to open file '"
+ file.getName() + "'");
} catch (IOException ex) {
System.out.println("Error reading file '"
+ file.getName() + "'");
// Or we could just do this:
ex.printStackTrace();
}
}
}
}
}
}
Ответ 18
вы должны поместить свою "системную переменную" в путь класса java.