read - Cómo leer realmente el archivo de texto de classpath en Java
java read file from classpath (16)
Estoy tratando de leer un archivo de texto que se establece en la variable de sistema CLASSPATH. No es una variable de usuario.
Estoy tratando de obtener la secuencia de entrada al archivo de la siguiente manera:
Coloque el directorio del archivo ( D:/myDir
) en CLASSPATH e intente a continuación:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt");
Coloque la ruta completa del archivo ( D:/myDir/SomeTextFile.txt
) en CLASSPATH e intente lo mismo con las 3 líneas de código anteriores.
Pero desafortunadamente, ninguno de ellos está funcionando y siempre me estoy quedando null
en mi InputStream.
Así es como leo todas las líneas de un archivo de texto en mi classpath, utilizando 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 este es un ejemplo de cómo se puede hacer. Tendrás que hacer mejoras según sea necesario. Este ejemplo solo funcionará si el archivo está realmente presente en su ruta de clase, de lo contrario se lanzará una NullPointerException cuando getResource () devuelva nulo y se invoque .toURI ().
Además, desde Java 7, una forma conveniente de especificar conjuntos de caracteres es usar las constantes definidas en java.nio.charset.StandardCharsets
(estas son, según sus javadocs , "garantizadas para estar disponibles en cada implementación de la plataforma Java". ).
Por lo tanto, si sabe que la codificación del archivo es UTF-8, especifique explícitamente el conjunto de caracteres StandardCharsets.UTF_8
Con el directorio en el classpath, desde una clase cargada por el mismo classloader, debería poder usar cualquiera de:
// From ClassLoader, all paths are "absolute" already - there''s 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");
Si esos no funcionan, eso sugiere que algo más está mal.
Así por ejemplo, toma este código:
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);
}
}
Y esta estructura de directorios:
code
dummy
Test.class
txt
SomeTextFile.txt
Y luego (usando el separador de ruta de Unix como estoy en un cuadro de Linux):
java -classpath code:txt dummy.Test
Resultados:
true
true
Cuando use Spring Framework (ya sea como una colección de utilidades o contenedor, no necesita usar la última funcionalidad) puede usar fácilmente la abstracción de recursos .
Resource resource = new ClassPathResource("com/example/Foo.class");
A través de la interfaz de recursos , puede acceder al recurso como InputStream , URL , URI o Archivo . Cambiar el tipo de recurso a, por ejemplo, un recurso del sistema de archivos es simplemente una cuestión de cambiar la instancia.
De alguna manera, la mejor respuesta no funciona para mí. Necesito usar un código ligeramente diferente en su lugar.
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("SomeTextFile.txt");
Espero que esto ayude a aquellos que se encuentran con el mismo problema.
Estoy usando el servidor de aplicaciones webshpere y mi módulo web se basa en Spring MVC. Las Test.properties
estaban ubicadas en la carpeta de recursos, traté de cargar estos archivos usando lo siguiente:
-
this.getClass().getClassLoader().getResourceAsStream("Test.properties");
-
this.getClass().getResourceAsStream("/Test.properties");
Ninguno de los códigos anteriores cargó el archivo.
Pero con la ayuda del siguiente código, el archivo de propiedad se cargó correctamente:
Thread.currentThread().getContextClassLoader().getResourceAsStream("Test.properties");
Gracias al usuario "user1695166" .
No use el método getClassLoader () y use "/" antes del nombre del archivo. "/" es muy importante
this.getClass().getResourceAsStream("/SomeTextFile.txt");
Para leer el contenido de un archivo en una cadena de la classpath
, puede usar esto:
private String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath))
{
return IOUtils.toString(inputStream);
}
}
Nota:
IOUtils
es parte de Commons IO
.
Llámalo así:
String fileContents = resourceToString("ImOnTheClasspath.txt");
Para leer realmente el contenido del archivo, me gusta usar Commons IO + Spring Core. Asumiendo Java 8:
try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) {
IOUtils.toString(stream);
}
Alternativamente:
InputStream stream = null;
try {
stream = new ClassPathResource("/log4j.xml").getInputStream();
IOUtils.toString(stream);
} finally {
IOUtils.closeQuietly(stream);
}
Para obtener la ruta absoluta de clase intente esto:
String url = this.getClass().getResource("").getPath();
Por favor, inténtalo
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
Sus intentos no funcionaron porque solo el cargador de clases para sus clases puede cargarse desde el classpath. Usaste el cargador de clases para el sistema java mismo.
Si usas guayaba:
import com.google.common.io.Resources;
Podemos obtener URL de CLASSPATH:
URL resource = Resources.getResource("test.txt");
String file = resource.getFile(); // get file path
o InputStream:
InputStream is = Resources.getResource("test.txt").openStream();
Usted dice "Estoy tratando de leer un archivo de texto que se establece en la variable de sistema CLASSPATH". Supongo que esto está en Windows y está utilizando este cuadro de diálogo feo para editar las "Variables del sistema".
Ahora ejecuta su programa Java en la consola. Y eso no funciona: la consola obtiene una copia de los valores de las variables del sistema una vez que se inicia . Esto significa que cualquier cambio en el diálogo después no tiene ningún efecto.
Hay estas soluciones:
Iniciar una nueva consola después de cada cambio.
Use
set CLASSPATH=...
en la consola para establecer la copia de la variable en la consola y cuando su código funcione, pegue el último valor en el cuadro de diálogo de la variable.Ponga la llamada a Java en el archivo
.BAT
y haga doble clic en él. Esto creará una nueva consola cada vez (copiando así el valor actual de la variable del sistema).
CUIDADO: si también tiene una variable de usuario CLASSPATH
entonces CLASSPATH
su variable de sistema. Es por eso que generalmente es mejor poner la llamada a su programa Java en un archivo .BAT
y configurar la ruta de clase allí (usando el set CLASSPATH=
) en lugar de confiar en un sistema global o variable de usuario.
Esto también asegura que puede tener más de un programa Java trabajando en su computadora porque están obligados a tener diferentes classpaths.
Utilice org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));
tienes que poner tu ''variable de sistema'' en el classpath de java.
Guión:
1) client-service-1.0-SNAPSHOT.jar
tiene dependencia read-classpath-resource-1.0-SNAPSHOT.jar
2) queremos leer el contenido de los recursos de ruta de clase ( sample.txt
) de read-classpath-resource-1.0-SNAPSHOT.jar
través de client-service-1.0-SNAPSHOT.jar
.
3) read-classpath-resource-1.0-SNAPSHOT.jar
tiene src/main/resources/sample.txt
Aquí está el código de muestra de trabajo que preparé, después de 2-3 días perdiendo mi tiempo de desarrollo, encontré la solución completa de extremo a extremo, espero que esto ayude a ahorrar tiempo.
1. pom.xml
de 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. Clase ClassPathResourceReadTest.java
en read-classpath-resource-1.0-SNAPSHOT.jar
que carga el contenido del archivo de recursos de ruta de clase.
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
de 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
instancia de la clase ClassPathResourceReadTest.java
donde se va a cargar sample.txt
e imprime su contenido también.
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. Ejecutar el archivo ejecutable de la siguiente manera:
[ravibeli@localhost 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
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();
}
}
}
}
}
}