java

Muchas veces al momento de realizar nuestros proyectos se presenta la necesidad de procesar archivos de texto, los mismos pueden llegar a contener información muy importante que con el pasar del tiempo puede llegar a tener un gran tamaño.

Procesar esta información a través de los métodos tradicionales puede llegar a tomar mucho tiempo y en este artículo te presentamos algunos métodos para realizar esta tarea de manera óptima.

En este artículo, veremos cómo podemos leer un archivo desde un classpath, URL o dentro de un archivo JAR, utilizando clases estándar de Java.

Lo que necesitaremos

Para poder realizar esta tarea usaremos un conjunto de ejemplos de prueba que usen solo clases principales de Java, y en las pruebas, usaremos aserciones usando los marcadores de Hamcrest.

Las pruebas compartirán un método común readFromInputStream que transforma un InputStream en String para facilitar la afirmación de los resultados:

private String readFromInputStream(InputStream inputStream)
  throws IOException {
    StringBuilder resultStringBuilder = new StringBuilder();
    try (BufferedReader br
      = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
    }
  return resultStringBuilder.toString();
}

Leer archivo de Classpath

Esta sección te mostramos cómo leer un archivo que está disponible en un classpath. Leeremos el “file.txt” disponible en src/main/resources:

@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
     
    Class clazz = FileOperationsTest.class;
    InputStream inputStream = clazz.getResourceAsStream("/file.txt");
    String data = readFromInputStream(inputStream);
 
    Assert.assertThat(data, containsString(expectedData));
}

En el fragmento de código anterior, usamos la clase actual para cargar un archivo usando el método getResourceAsStream y pasamos la ruta absoluta del archivo para cargar.

El mismo método está disponible en una instancia de ClassLoader también:

ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("file.txt");
String data = readFromInputStream(inputStream);

Obtenemos el classLoader de la clase actual usando getClass(),  GetClassLoader().

La principal diferencia es que cuando se usa getResourceAsStream en una instancia de ClassLoader, la ruta se trata como absoluta desde la raíz de la ruta de clase.

Cuando se usa en una instancia de Clase, la ruta puede ser relativa al paquete, o una ruta absoluta, que se insinúa por la barra diagonal.

Por supuesto, tenga en cuenta que, en la práctica, las transmisiones abiertas siempre deben estar cerradas, como el InputStream en nuestro ejemplo:

InputStream inputStream = null;
try {
    File file = new File(classLoader.getResource("file.txt").getFile());
    inputStream = new FileInputStream(file);
     
    //tu codigo para el proceso
}     
finally {
    if (inputStream != null) {
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Leer el archivo con JDK 8

Veamos un ejemplo de cómo leer datos en bytes y decodificar usando el juego de caracteres UTF-8:

@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
          
    Path path = Paths.get(getClass().getClassLoader()
      .getResource("file.txt").toURI());
          
    StringBuilder data = new StringBuilder();
    Stream<String> lines = Files.lines(path);
    lines.forEach(line -> data.append(line).append("\n"));
    lines.close();
          
    Assert.assertEquals(expectedData, data.toString().trim());
}

Algo importante al utilizar Stream con canales IO como las operaciones de archivo, debemos cerrar la transmisión de manera explícita utilizando el método close().

Leer archivo con FileUtils

Para poder utilizar un útil, debemos agregarlo a nuestro proyecto la respectiva dependencia, para este ejemplo:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

Al momento de desarrollar es una muy buena práctica siempre utilizar las últimas versiones de las librerías, si quieres verificar que la librería que tienes es la última puedes hacerlo en este link.

Ahora con el siguiente código podemos realizar justamente la lectura de manera fácil y sencilla utilizando esta librería, la cual desde ya recomendamos como la mejor opción entre las opciones que te mostramos en este articulo.

@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
         
    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("file.txt").getFile());
    String data = FileUtils.readFileToString(file);
         
    Assert.assertEquals(expectedData, data.trim());
}

En este ejemplo pasamos el objeto File al método readFileToString () de la clase FileUtils. Esta clase de utilidad logra cargar el contenido sin la necesidad de escribir ningún código repetitivo para crear una instancia de InputStream y leer datos.

Leer contenido de URL

Para leer el contenido de la URL, utilizaremos la URL “/” en nuestro ejemplo como:

@Test
public void givenURLName_whenUsingURL_thenFileData() {
    String expectedData = "RootNite";
 
    URL urlObject = new URL("/");
    URLConnection urlConnection = urlObject.openConnection();
    InputStream inputStream = urlConnection.getInputStream();
    String data = readFromInputStream(inputStream);
 
    Assert.assertThat(data, containsString(expectedData));
}

También hay formas alternativas de conectarse a una URL. Aquí usamos la URL y la clase URLConnection disponibles en el SDK estándar.

En este tutorial, hemos visto cómo leer un archivo desde varias ubicaciones, como classpath, URL o archivos jar.

También demostramos una lectura de datos de archivos que utilizan la API central de Java. Ahora turno para ti, cuéntanos ¿Que método utilizas en la lectura de archivos de tus proyectos con Java 8?

 

Dejar respuesta

Please enter your comment!
Please enter your name here