Cómo leer realmente el archivo de texto de classpath en Java

Estoy tratando de leer un archivo de texto que está configurado en la variable del sistema CLASSPATH. No es una variable de usuario.

Estoy tratando de obtener flujo 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 por encima de 3 líneas de código.

Pero desafortunadamente NINGUNO de ellos están funcionando y siempre estoy obteniendo null en mi InputStream in .

Con el directorio en el classpath, de una clase cargada por el mismo cargador de clases, 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 eso no funciona, eso sugiere que algo más está mal.

Entonces, 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 directorio:

 code dummy Test.class txt SomeTextFile.txt 

Y luego (utilizando el separador de ruta de Unix como estoy en una caja de Linux):

 java -classpath code:txt dummy.Test 

Resultados:

 true true 

Al utilizar Spring Framework (ya sea como una colección de utilidades o un contenedor, no es necesario que use 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 una simple cuestión de cambiar la instancia.

Así es como leo todas las líneas de un archivo de texto en mi classpath, usando 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()); 

Nota: 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 classpath, de lo contrario se lanzará una NullPointerException cuando getResource () devuelva null y se invoque .toURI () en él.

Además, desde Java 7, una manera conveniente de especificar juegos de caracteres es usar las constantes definidas en java.nio.charset.StandardCharsets (estos están, según sus javadocs , “garantizados para estar disponibles en cada implementación de la plataforma Java”). )

Por lo tanto, si sabe que la encoding del archivo es UTF-8, especifique explícitamente el juego de caracteres StandardCharsets.UTF_8

Por favor, inténtalo

 InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt"); 

Tus bashs no funcionaron porque solo el cargador de clases de tus clases puede cargar desde classpath. Usaste el cargador de clases para el sistema java en sí.

Para leer el contenido del archivo, me gusta usar Commons IO + Spring Core. Suponiendo que 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 el camino absoluto de la clase, intente esto:

 String url = this.getClass().getResource("").getPath(); 

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 encuentren el mismo problema.

Si usas Guava:

 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(); 

Para leer el contenido de un archivo en un String desde 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"); 

Dice “Intento leer un archivo de texto que está configurado en la variable de sistema CLASSPATH”. Supongo que esto está en Windows y estás usando este desagradable diálogo para editar las “Variables del sistema”.

Ahora ejecuta su progtwig Java en la consola. Y eso no funciona: la consola obtiene una copia de los valores de las variables del sistema una vez cuando se inicia . Esto significa que cualquier cambio en el diálogo posterior no tiene ningún efecto.

Hay estas soluciones:

  1. Comience una nueva consola después de cada cambio

  2. 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.

  3. Ponga la llamada a Java en el archivo .BAT y haga doble clic en él. Esto creará una consola nueva cada vez (copiando así el valor actual de la variable del sistema).

ATENCIÓN: si también tiene una variable de usuario CLASSPATH , sombreará la variable de su sistema. Es por eso que generalmente es mejor colocar la llamada a su progtwig Java en un archivo .BAT y establecer el classpath allí (usando set CLASSPATH= ) en lugar de depender de un sistema global o variable de usuario.

Esto también asegura que puede tener más de un progtwig Java trabajando en su computadora porque están obligados a tener diferentes classpaths.

Cada vez que agregue un directorio a la ruta de clase, todos los recursos definidos en ella se copiarán directamente debajo de la carpeta de implementación de la aplicación (por ejemplo, bin ).

Para acceder a un recurso desde su aplicación, puede usar el prefijo ‘/’ que apunta a la ruta raíz de la carpeta de despliegue, las otras partes de la ruta dependen de la ubicación de su recurso (ya sea directamente debajo de “D: \ myDir “ o nested bajo una subcarpeta)

Consulte este tutorial para obtener más información.

En su ejemplo, debe poder acceder a su recurso a través de lo siguiente:

 InputStream is = getClass().getResourceAsStream("/SomeTextFile.txt"); 

Sabiendo que “SomeTextFile.txt” existe directamente debajo de “D: \ myDir”

Guión:

1) client-service-1.0-SNAPSHOT.jar tiene la 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 desperdiciando 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

   4.0.0 jar-classpath-resource read-classpath-resource 1.0-SNAPSHOT classpath-test  UTF-8 4.3.3.RELEASE 2.5.1 ${project.artifactId} 1.0.3 2.4    org.springframework spring-core ${org.springframework.version}   org.springframework spring-context ${org.springframework.version}   commons-io commons-io ${commons-io.verion}      src/main/resources     org.apache.maven.plugins maven-release-plugin ${mvn.release.plugin}   org.apache.maven.plugins maven-compiler-plugin 3.1  1.8 1.8 UTF-8    maven-jar-plugin 2.5  ${project.build.directory}/lib   true false true demo.read.classpath.resources.ClassPathResourceReadTest   ${project.artifactId} sample.txt      org.apache.maven.plugins maven-shade-plugin 2.2  false   *:*  META-INF/*.SF META-INF/*.DSA META-INF/*.RSA       package  shade      demo.read.classpath.resources.ClassPathResourceReadTest          

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 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

   4.0.0 client-service client-service 1.0-SNAPSHOT   jar-classpath-resource read-classpath-resource 1.0-SNAPSHOT      maven-jar-plugin 2.5  ${project.build.directory}/lib   true false true com.crazy.issue.client.AccessClassPathResource   ${project.artifactId} ${buildNumber} sample.txt      org.apache.maven.plugins maven-shade-plugin 2.2  false   *:*  META-INF/*.SF META-INF/*.DSA META-INF/*.RSA       package  shade      com.crazy.issue.client.AccessClassPathResource          

4. AccessClassPathResource.java instancia de la clase ClassPathResourceReadTest.java donde, cargará sample.txt e imprimirá también su contenido.

 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 

Estoy usando el servidor de aplicaciones webshpere y mi módulo web está basado en Spring MVC. The Test.properties se ubicaron en la carpeta de recursos, intenté cargar estos archivos usando lo siguiente:

  1. this.getClass().getClassLoader().getResourceAsStream("Test.properties");
  2. this.getClass().getResourceAsStream("/Test.properties");

Ninguno del código anterior 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” .

Use org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));

No use el método getClassLoader () y use “/” antes del nombre del archivo. “/” es muy importante

 this.getClass().getResourceAsStream("/SomeTextFile.txt"); 
 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(); } } } } } } 

tienes que poner tu ‘variable de sistema’ en el classpath java.