¿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.
¿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.
Respuestas:
Sí, Guava ofrece esto en la Resources
clase. Por ejemplo:
URL url = Resources.getResource("foo.txt");
String text = Resources.toString(url, StandardCharsets.UTF_8);
getResource
está utilizando, Resource.class.getClassLoader
pero en aplicaciones web, esto podría no ser "su" cargador de clases, por lo que se recomienda (por ejemplo, en [1]) usar Thread.currentThread().getContextClassLoader().getResourceAsStream
en su lugar (referencia [1]: stackoverflow.com/questions/676250/… )
Resources.toString(MyClass.getResource("foo.txt"), Charsets.UTF_8)
que garantiza el uso del cargador de clases correcto.
com.google.common.io.Resources
está marcado como inestable según SonarQube
guava
ha cambiado la implementación. Para la guayaba 23, a la implementación le gusta seguir. ClassLoader loader = MoreObjects.firstNonNull( Thread.currentThread().getContextClassLoader(), Resources.class.getClassLoader());
Puede usar el viejo truco en línea Stupid Scanner para hacer eso sin ninguna dependencia adicional como guayaba:
String text = new Scanner(AppropriateClass.class.getResourceAsStream("foo.txt"), "UTF-8").useDelimiter("\\A").next();
Chicos, no utilicen material de terceros a menos que realmente lo necesiten. Ya hay mucha funcionalidad en el JDK.
CartApplication.class.getResourceAsStream
a CartApplication.class.getClassLoader().getResourceAsStream
para cargar recursos en el jar actual ... como srm / test / resources
Para java 7:
new String(Files.readAllBytes(Paths.get(getClass().getResource("foo.txt").toURI())));
getClass().getClassLoader()
pero por lo demás una gran solución!
Este simple método 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 funciona con recursos en archivos jar .
Acerca de la codificación de texto: InputStreamReader
utilizará el juego 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);
Siempre prefiera no depender de bibliotecas grandes y gordas. A menos que ya esté utilizando Guava o Apache Commons IO para otras tareas, agregar esas bibliotecas a su proyecto solo para poder leer desde un archivo parece demasiado.
Entiendo que Java puro no hace un buen trabajo cuando se trata de hacer 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 a su proyecto y usarlo. Ni siquiera te pido que entiendas lo que está sucediendo allí, porque realmente no le importa a nadie. Simplemente funciona, punto :-)
InputStream
variable is
es null
o no.
La 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 ).
String stringFromStream = CharStreams.toString(new InputStreamReader(resourceAsStream, "UTF-8"));
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");
IOUtils.toString(this.getClass().getResource("foo.xml"), "UTF-8")
.
getClassLoader()
a la cadena de métodos: String text = IOUtils.toString( getClass().getClassLoader().getResourceAsStream("foo.xml"), StandardCharsets.UTF_8);
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
A menudo tuve este problema yo mismo. Para evitar dependencias en proyectos pequeños, a menudo escribo una pequeña función de utilidad cuando no necesito commons io o tal. Aquí está el código para cargar el contenido del archivo en un búfer de cadena:
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("path/to/textfile.txt"), "UTF-8"));
for (int c = br.read(); c != -1; c = br.read()) sb.append((char)c);
System.out.println(sb.toString());
En ese caso, es importante especificar la codificación , porque es posible que haya editado su archivo en UTF-8 y luego lo haya colocado en un archivo jar, y la computadora que abre el archivo puede tener CP-1251 como codificación de archivo nativa (por ejemplo) ; así que en este caso nunca se conoce la codificación de destino, por lo tanto, la información de codificación explícita es crucial. Además, el bucle para leer el archivo char por char parece ineficiente, pero se usa en un BufferedReader y, por lo tanto, en realidad es bastante rápido.
Puede usar el siguiente código de Java
new String(Files.readAllBytes(Paths.get(getClass().getResource("example.txt").toURI())));
Si desea obtener su Cadena de un recurso de proyecto como el archivo testcase / foo.json en src / main / resources en su proyecto, haga lo siguiente:
String myString=
new String(Files.readAllBytes(Paths.get(getClass().getClassLoader().getResource("testcase/foo.json").toURI())));
Tenga en cuenta que falta el método getClassLoader () en algunos de los otros ejemplos.
Use FileUtils de Apache commons. Tiene un método readFileToString
Estoy usando lo siguiente para leer archivos de recursos de classpath
:
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Scanner;
public class ResourceUtilities
{
public static String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = ResourceUtilities.class.getClassLoader().getResourceAsStream(filePath))
{
return inputStreamToString(inputStream);
}
}
private static String inputStreamToString(InputStream inputStream)
{
try (Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"))
{
return scanner.hasNext() ? scanner.next() : "";
}
}
}
No se requieren dependencias de terceros.
Con un conjunto de importaciones estáticas, la solución de guayaba puede ser muy compacta:
toString(getResource("foo.txt"), UTF_8);
Se requieren las siguientes importaciones:
import static com.google.common.io.Resources.getResource
import static com.google.common.io.Resources.toString
import static java.nio.charset.StandardCharsets.UTF_8
package test;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
try {
String fileContent = getFileFromResources("resourcesFile.txt");
System.out.println(fileContent);
} catch (Exception e) {
e.printStackTrace();
}
}
//USE THIS FUNCTION TO READ CONTENT OF A FILE, IT MUST EXIST IN "RESOURCES" FOLDER
public static String getFileFromResources(String fileName) throws Exception {
ClassLoader classLoader = Main.class.getClassLoader();
InputStream stream = classLoader.getResourceAsStream(fileName);
String text = null;
try (Scanner scanner = new Scanner(stream, StandardCharsets.UTF_8.name())) {
text = scanner.useDelimiter("\\A").next();
}
return text;
}
}
Al menos a partir de Apache commons-io 2.5, el método IOUtils.toString () admite un argumento URI y devuelve el contenido de los archivos ubicados dentro de los frascos en el classpath:
IOUtils.toString(SomeClass.class.getResource(...).toURI(), ...)
Me gusta la respuesta de akosicki con Stupid Scanner Trick. Es lo más simple que veo sin dependencias externas que funciona en Java 8 (y de hecho hasta Java 5). Aquí hay una respuesta aún más simple si puede usar Java 9 o superior (ya que InputStream.readAllBytes()
se agregó en Java 9):
String text = new String(AppropriateClass.class.getResourceAsStream("foo.txt").readAllBytes());
La guayaba también tiene Files.readLines()
si desea un valor de retorno como List<String>
línea por línea:
List<String> lines = Files.readLines(new File("/file/path/input.txt"), Charsets.UTF_8);
Consulte aquí para comparar 3 formas ( BufferedReader
frente a Guava's Files
versus Guava's Resources
) para obtener String
de un archivo de texto.
Charsets
también está en Guava. Vea esto: google.github.io/guava/releases/23.0/api/docs
Aquí está mi enfoque funcionó bien
public String getFileContent(String fileName) {
String filePath = "myFolder/" + fileName+ ".json";
try(InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath)) {
return IOUtils.toString(stream, "UTF-8");
} catch (IOException e) {
// Please print your Exception
}
}
He escrito métodos readResource () aquí , para poder hacerlo en una simple invocación. Depende de la biblioteca de Guava, pero me gustan los métodos solo JDK sugeridos en otras respuestas y creo que los cambiaré de esa manera.
Aquí hay una solución que usa Java 11 Files.readString
:
public class Utils {
public static String readResource(String name) throws URISyntaxException, IOException {
var uri = Utils.class.getResource("/" + name).toURI();
var path = Paths.get(uri);
return Files.readString(path);
}
}
Hice un método estático de NO dependencia como este:
import java.nio.file.Files;
import java.nio.file.Paths;
public class ResourceReader {
public static String asString(String resourceFIleName) {
try {
return new String(Files.readAllBytes(Paths.get(new CheatClassLoaderDummyClass().getClass().getClassLoader().getResource(resourceFIleName).toURI())));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class CheatClassLoaderDummyClass{//cheat class loader - for sql file loading
}
Me gustan las utilidades de Apache commons para este tipo de cosas y uso este caso de uso exacto (lectura de archivos de classpath) ampliamente cuando se realizan pruebas, especialmente para leer archivos JSON /src/test/resources
como parte de las pruebas de unidad / integración. p.ej
public class FileUtils {
public static String getResource(String classpathLocation) {
try {
String message = IOUtils.toString(FileUtils.class.getResourceAsStream(classpathLocation),
Charset.defaultCharset());
return message;
}
catch (IOException e) {
throw new RuntimeException("Could not read file [ " + classpathLocation + " ] from classpath", e);
}
}
}
Para fines de prueba, puede ser agradable atrapar IOException
y lanzar un RuntimeException
- su clase de prueba podría verse, por ejemplo,
@Test
public void shouldDoSomething () {
String json = FileUtils.getResource("/json/input.json");
// Use json as part of test ...
}
public static byte[] readResoureStream(String resourcePath) throws IOException {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
InputStream in = CreateBffFile.class.getResourceAsStream(resourcePath);
//Create buffer
byte[] buffer = new byte[4096];
for (;;) {
int nread = in.read(buffer);
if (nread <= 0) {
break;
}
byteArray.write(buffer, 0, nread);
}
return byteArray.toByteArray();
}
Charset charset = StandardCharsets.UTF_8;
String content = new String(FileReader.readResoureStream("/resource/...*.txt"), charset);
String lines[] = content.split("\\n");