Utils para leer el archivo de texto de recursos en String (Java) [closed]

9 minutos de lectura

avatar de usuario
Ubicación Phan

¿Hay alguna utilidad que ayude a leer un archivo de texto en el recurso en una cadena? Supongo que este es un requisito popular, pero no pude encontrar ninguna utilidad después de buscar en Google.

  • aclare lo que quiere decir con “archivo de texto de recurso” frente a “archivo de texto en recurso”; no es fácil entender lo que está tratando de lograr.

    – Estera

    20 de mayo de 2011 a las 6:27

  • Eso es solo un archivo de texto en classpath como “classpath*:mytext/text.txt”

    – Loc Fan

    20 de mayo de 2011 a las 6:29

  • Desde java11 hay un método específico para esto: Files.readString(Paths.get(getClass().getResource("foo.txt").toURI()), Charset.forName("utf-8"))

    – roberto

    20 de febrero de 2021 a las 14:57

  • LOLz, estoy completamente seguro de que todo el mundo está completamente seguro de qué se trata esta pregunta ;-]Sin embargo, algunas personas decidieron que necesitaban demostrar que son importantes, por lo que decidieron mantenerlo cerrado como una demostración de su “poder” ;-]Ahora las nuevas respuestas que usan las nuevas características de Java no pueden ser agregado (ver, por ejemplo, la respuesta de Roberto en el comentario anterior). SO comunidad en su mejor momento ;-]

    – morgwai

    8 oct 2021 a las 15:31


  • @Roberto, su método funciona cuando ejecuto mi programa desde una carpeta ampliada con clases, pero cuando lo empaqueto en un contenedor, Paths.get(...) lanza FileSystemNotFoundException

    – morgwai

    9 de octubre de 2021 a las 4:56


avatar de usuario
jon skeet

Sí, Guayaba proporciona esto en el Resources clase. Por ejemplo:

URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);

  • @JonSkeet Esto es genial, sin embargo, para aplicaciones web podría no ser la mejor solución, la implementación de getResource esta usando Resource.class.getClassLoader pero en las aplicaciones web, este podría no ser “su” cargador de clases, por lo que se recomienda (por ejemplo, en [1]) usar Thread.currentThread().getContextClassLoader().getResourceAsStream en cambio (referencia [1]: stackoverflow.com/questions/676250/…)

    –Eran Medan

    13 de junio de 2013 a las 20:21


  • @EranMedan: Sí, si desea el cargador de clases de contexto, querrá usarlo explícitamente.

    – Jon Skeet

    13 de junio de 2013 a las 20:24

  • En el caso especial cuando el recurso está al lado de su clase, puede hacer Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8) lo que garantiza el uso del cargador de clases correcto.

    -Bogdan Calmac

    5 de marzo de 2015 a las 17:46

  • com.google.common.io.Resources está marcado como inestable según SonarQube

    – Gilteras

    11 de junio de 2019 a las 1:00

  • guava ha cambiado la implementación. Para guayaba 23 la implementación le gusta siguiente. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());

    – xxi

    22 de febrero de 2020 a las 12:18


avatar de usuario
akosicki

Puedes usar el viejo Estúpido truco del escáner oneliner para hacer eso sin ninguna dependencia adicional como la guayaba:

String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();

Chicos, no usen material de terceros a menos que realmente lo necesiten. Ya hay mucha funcionalidad en el JDK.

  • Evitar terceros es un principio razonable. Desafortunadamente, la biblioteca central parece alérgica al modelado de casos de uso de la vida real. Mire los archivos de Java 7 y dígame por qué no se incluyó allí la lectura de todo desde un recurso classpath. O al menos usando un ‘sistema de archivos’ estandarizado.

    – Dilum Ranatunga

    07/03/2014 a las 18:36

  • ¿Es, o no, necesario cerrar la transmisión también? La guayaba cierra internamente el arroyo.

    – virgo47

    12/11/2014 a las 13:50

  • ¡Funcionó maravillosamente para mí también! También estoy de acuerdo con lo de terceros: en muchas respuestas, la respuesta predeterminada siempre parece ser usar alguna biblioteca de terceros, ya sea de Apache o de otra persona.

    – Terje Dahl

    5 de abril de 2015 a las 8:01

  • cambio CartApplication.class.getResourceAsStream a CartApplication.class.getClassLoader().getResourceAsStream para cargar recursos en el contenedor actual… como srm/test/resources

    – Chris DaMour

    27 de febrero de 2016 a las 6:38

  • Si bien he usado esto, no estoy de acuerdo en evitar paquetes de terceros. El hecho de que en Java, la única forma de leer fácilmente un archivo en una cadena es con el truco del escáner es bastante triste. La alternativa al uso de una librería de terceros es que todos simplemente crearán sus propios contenedores. Guayaba para IO sin duda gana si tiene muchas necesidades para este tipo de operación. Donde estaré de acuerdo es que no debe importar un paquete de terceros si solo tiene un lugar en su código donde desea hacer esto. Eso sería una exageración en mi opinión.

    – Kenny Cason

    30 de marzo de 2016 a las 22:21

avatar de usuario
Kovalski Dmitryi

Para Java 7:

new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));

ParaJava 11:

Files.readString(Paths.get(getClass().getResource("foo.txt").toURI()));

  • Explique por qué funciona esto, por qué es mejor que otras alternativas y cualquier consideración de rendimiento/codificación necesaria.

    – nanofaradio

    17/10/2014 a las 10:12

  • Es nio 2 en java 1.7. Es característica nativa de Java. Para codificar, use una nueva cadena (bytes, StandardCharsets.UTF_8)

    – Kovalski Dmitryi

    17/10/2014 a las 11:29


  • en mi caso necesitaba getClass().getClassLoader() pero por lo demás gran solución!

    –Emanuel Touzery

    2 dic 2016 a las 20:02

  • Esto no funcionará una vez que la aplicación esté empaquetada en un contenedor.

    – Daniel Bo

    9 oct 2018 a las 14:53

avatar de usuario
lucio paiva

Solución Java 8+ pura y simple, compatible con jar

Este método simple a continuación funcionará bien si está utilizando Java 8 o superior:

/**
 * Reads given resource file as a string.
 *
 * @param fileName path to the resource file
 * @return the file's contents
 * @throws IOException if read fails for any reason
 */
static String getResourceFileAsString(String fileName) throws IOException {
    ClassLoader classLoader = ClassLoader.getSystemClassLoader();
    try (InputStream is = classLoader.getResourceAsStream(fileName)) {
        if (is == null) return null;
        try (InputStreamReader isr = new InputStreamReader(is);
             BufferedReader reader = new BufferedReader(isr)) {
            return reader.lines().collect(Collectors.joining(System.lineSeparator()));
        }
    }
}

y también trabaja con recursos en archivos jar.

Acerca de la codificación de texto: InputStreamReader utilizará el conjunto de caracteres predeterminado del sistema en caso de que no especifique uno. Es posible que desee especificarlo usted mismo para evitar problemas de decodificación, como este:

new InputStreamReader(isr, StandardCharsets.UTF_8);

Evita dependencias innecesarias

Siempre prefiera no depender de bibliotecas grandes y gordas. A menos que ya esté usando Guava o Apache Commons IO para otras tareas, agregar esas bibliotecas a su proyecto solo para poder leer desde un archivo parece demasiado.

¿Método “sencillo”? debes estar bromeando

Entiendo que Java puro no hace un buen trabajo cuando se trata de realizar tareas simples como esta. Por ejemplo, así es como leemos de un archivo en Node.js:

const fs = require("fs");
const contents = fs.readFileSync("some-file.txt", "utf-8");

Simple y fácil de leer (aunque a la gente todavía le gusta confiar en muchas dependencias de todos modos, principalmente debido a la ignorancia). O en Python:

with open('some-file.txt', 'r') as f:
    content = f.read()

Es triste, pero sigue siendo simple para los estándares de Java y todo lo que tiene que hacer es copiar el método anterior en su proyecto y usarlo. Ni siquiera les pido que entiendan lo que está pasando ahí adentro, porque realmente no le importa a nadie. Simplemente funciona, punto 🙂

avatar de usuario
Luciano Fiandesio

Guayaba tiene un método “toString” para leer un archivo en una cadena:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

String content = Files.toString(new File("/home/x1/text.log"), Charsets.UTF_8);

Este método no requiere que el archivo esté en el classpath (como en la respuesta anterior de Jon Skeet).

  • O si se trata de un flujo de entrada, la guayaba también tiene una buena manera de hacerlo. String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));

    –Eran Medan

    13 de junio de 2013 a las 20:10


  • Esto está en desuso en Guava 24.1

    – Andrei

    24 de abril de 2018 a las 18:54

avatar de usuario
Comunidad

yegor256 ha encontrado una buena solución usando Apache Commons IO:

import org.apache.commons.io.IOUtils;

String text = IOUtils.toString(this.getClass().getResourceAsStream("foo.xml"),
                               "UTF-8");

  • O si se trata de un flujo de entrada, la guayaba también tiene una buena manera de hacerlo. String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));

    –Eran Medan

    13 de junio de 2013 a las 20:10


  • Esto está en desuso en Guava 24.1

    – Andrei

    24 de abril de 2018 a las 18:54

avatar de usuario
edd

apache-commons-io tiene un nombre de utilidad FileUtils:

URL url = Resources.getResource("myFile.txt");
File myFile = new File(url.toURI());

String content = FileUtils.readFileToString(myFile, "UTF-8");  // or any other encoding

  • ¿Por qué uno tiene que especificar la codificación? No lo entiendo. Si leo el archivo, solo quiero lo que contiene, debería averiguar qué codificación es como lo hace mi editor. Cuando abro en el Bloc de notas o ++, no le digo qué codificación debe usar. Estoy usando este método y luego escriboStringToFile… pero los contenidos difieren. Obtengo tokens extraños en el archivo clonado… No entiendo por qué debería tener que especificar una codificación.

    – mjs

    20 de diciembre de 2011 a las 14:47

  • @Hamidan, elegir la codificación correcta es un algoritmo muy complejo. A menudo se implementa en el editor de texto, pero a veces no detectan la codificación correcta. No esperaría que una API de lectura de archivos incrustara un algoritmo tan complejo para leer mi archivo.

    – Vicente Roberto

    17 de enero de 2012 a las 11:06

  • @SecretService Además, esos algoritmos utilizan información como el idioma del sistema operativo, la configuración regional y otras configuraciones regionales, lo que significa que leer un archivo sin especificar una codificación puede funcionar en su configuración pero no en la de otra persona.

    – Feuermurmel

    28 de abril de 2014 a las 8:26

  • apache FileUtils.leerlíneas(archivo) y copyURLToFile (URL, tempFile).

    – Yash

    25 de febrero de 2016 a las 10:51


  • No creo que esto funcione si el recurso se encuentra dentro de un frasco. Entonces no será un archivo.

    – Ville Oikarinen

    9 de mayo de 2018 a las 9:08

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad