Leer y escribir Ficheros en Java 7

Java 7 : Leer y escribir ficheros de texto en Java

En Java 7 las clases más importantes para el tratamiento de ficheros de texto son:

  • Paths y Path – Localización del fichero o nombre, no su contenido.
  • Files - Operaciones con el contenido del fichero.
  • StandardCharsets y Charset - Para manejar la codificación del archivo de texto.
  • File.toPath – Método que permite interactuar con código antiguo a través del nuevo API java.nio

Las siguientes clases también son usadas de manera generalizada cuando trabajamos con ficheros de texto tanto en Java 7 como en versiones anteriores:

Cuando realizamos operaciones de lectura/escritura con ficheros de texto:

  • Frecuentemente será buena idea utilizar buffering (por defecto el tamaño son 8K)
  • Siempre tendremos que tener en cuenta el manejo de excepciones de IOException y FileNotFoundException.

java 7 : Codificación de caracteres

Para realizar operaciones sobre ficheros de texto en Java 7 tenemos que tener en cuenta que esas operaciones de lectura/escritura siempre usan una codificación de caracteres de manera implícita para traducir las cadenas de bytes en texto. Aquí es donde frecuentemente nos encontramos antes el primer problema. 

Las clases FileReader y FileWriter utilizan de manera implícita la codificación de caracteres del sistema. Sin embargo, no es apropiado utilizarlo debido a los problemas que puede ocasionar usar nuestro código en diferentes sistemas operativos por ejemplo. La manera correcta es emplear aquellas clases que nos obliguen a realizar una declaración explícita de la codificación de caracteres como por ejemplo:

 Java | 
 
 copy code |
?

1
FileInputStream fis = new FileInputStream("test.txt");
2
InputStreamReader in = new InputStreamReader(fis, "UTF-8");
3
 
4
FileOutputStream fos = new FileOutputStream("test.txt");
5
OutputStreamWriter out = new OutputStreamWriter(fos, "UTF-8");
6
 
7
Scanner scanner = new Scanner(file, "UTF-8"); 

java 7 + ejemplo 1

 Java | 
 
 copy code |
?

01
package es.ivoto.cera.config;
02
import java.io.BufferedReader;
03
import java.io.BufferedWriter;
04
import java.io.IOException;
05
import java.nio.charset.Charset;
06
import java.nio.charset.StandardCharsets;
07
import java.nio.file.Files;
08
import java.nio.file.Path;
09
import java.nio.file.Paths;
10
import java.util.Arrays;
11
import java.util.List;
12
import java.util.Scanner;
13
 
14
public class LeerEscribirFicheroTextoJDK7 {
15
 
16
  public static void main(String... aArgs) throws IOException{
17
   LeerEscribirFicheroTextoJDK7 text = new LeerEscribirFicheroTextoJDK7();
18
 
19
    //Tratamiento con fichero pequeño con Java 7
20
    List<String> lines = text.readSmallTextFile(FILE_NAME);
21
    log(lines);
22
    lines.add("Esta es una línea añadida desde el código.");
23
    text.writeSmallTextFile(lines, FILE_NAME);
24
 
25
    //Tratamiento para ficheros grandes usando buffering
26
    text.readLargerTextFile(FILE_NAME);
27
    lines = Arrays.asList("Down to the Waterline", "Water of Love");
28
    text.writeLargerTextFile(OUTPUT_FILE_NAME, lines);   
29
  }
30
 
31
  final static String FILE_NAME = "C:\Temp\input.txt";
32
  final static String OUTPUT_FILE_NAME = "C:\Temp\output.txt";
33
  final static Charset ENCODING = StandardCharsets.UTF_8;
34
 
35
  //Para ficheros pequeños. Java 7
36
 
37
  /**
38
   Nota: el javadoc de Files.readAllLines dice que es recomendable para pequeños ficheros. 
39
   Pero su implementación usa buffering, por lo que también es recomendable para usarlo 
40
   con ficheros de texto de mayor tamaño.
41
  */  
42
  List<String> readSmallTextFile(String aFileName) throws IOException {
43
    Path path = Paths.get(aFileName);
44
    return Files.readAllLines(path, ENCODING);
45
  }
46
 
47
  void writeSmallTextFile(List<String> aLines, String aFileName) throws IOException {
48
    Path path = Paths.get(aFileName);
49
    Files.write(path, aLines, ENCODING);
50
  }
51
 
52
  //Para ficheros grandes Java 7
53
 
54
  void readLargerTextFile(String aFileName) throws IOException {
55
    Path path = Paths.get(aFileName);
56
    try (Scanner scanner =  new Scanner(path, ENCODING.name())){
57
      while (scanner.hasNextLine()){
58
        //procesa cada línea del mismo modo
59
        log(scanner.nextLine());
60
      }      
61
    }
62
  }
63
 
64
  void readLargerTextFileAlternate(String aFileName) throws IOException {
65
    Path path = Paths.get(aFileName);
66
    try (BufferedReader reader = Files.newBufferedReader(path, ENCODING)){
67
      String line = null;
68
      while ((line = reader.readLine()) != null) {
69
        //procesa cada línea del mismo modo
70
        log(line);
71
      }      
72
    }
73
  }
74
 
75
  void writeLargerTextFile(String aFileName, List<String> aLines) throws IOException {
76
    Path path = Paths.get(aFileName);
77
    try (BufferedWriter writer = Files.newBufferedWriter(path, ENCODING)){
78
      for(String line : aLines){
79
        writer.write(line);
80
        writer.newLine();
81
      }
82
    }
83
  }
84
 
85
  private static void log(Object aMsg){
86
    System.out.println(String.valueOf(aMsg));
87
  }
88
 
89
} 

java 7 + : Ejemplo 2

Este ejemplo muestra el uso de Scanner con Java 7 para leer un archivo que contiene las líneas de datos estructurados. Un Scanner se utiliza para leer en cada línea, y un segundo Scanner se utiliza para analizar cada línea en un simple par nombre-valor. La clase Scanner sólo se utiliza para la lectura, no para la escritura.

Java 7 : Clase Scanner
Java 7 : Clase Scanner

 Java | 
 
 copy code |
?

01
package es.ivoto.cera.config;
02
import java.io.IOException;
03
import java.nio.charset.Charset;
04
import java.nio.charset.StandardCharsets;
05
import java.nio.file.Path;
06
import java.nio.file.Paths;
07
import java.util.Scanner;
08
 
09
/**Asumimos que el fichero está codificado en UTF-8. Java 7 +. */
10
public class LeerConScanner {
11
 
12
  public static void main(String... aArgs) throws IOException {
13
    LeerConScanner parser = new LeerConScanner("C:\Temp\test.txt");
14
    parser.processLineByLine();
15
    log("Done.");
16
  }
17
 
18
  /**
19
   Constructor.
20
   @param aFileName nombre completo de un fichero existente.
21
  */
22
  public LeerConScanner(String aFileName){
23
    fFilePath = Paths.get(aFileName);
24
  }
25
 
26
 
27
  /** Método que invoca a {@link #processLine(String)}.  */
28
  public final void processLineByLine() throws IOException {
29
    try (Scanner scanner =  new Scanner(fFilePath, ENCODING.name())){
30
      while (scanner.hasNextLine()){
31
        processLine(scanner.nextLine());
32
      }      
33
    }
34
  }
35
 
36
  /** 
37
   Método sobreescribible para procesar las líneas de diferentes maneras.
38
    
39
   <P>La implementación por defecto espera recibir pares de clave-valor separados por un '='.
40
   Ejemplo de entradas válidas: 
41
   <tt>height = 178cm</tt>
42
   <tt>mass =  95kg</tt>
43
   <tt>disposition =  "grumpy"</tt>
44
   <tt>Clave = valor</tt>
45
  */
46
  protected void processLine(String aLine){
47
     Scanner scanner = new Scanner(aLine);
48
    scanner.useDelimiter("=");
49
    if (scanner.hasNext()){
50
      String name = scanner.next();
51
      String value = scanner.next();
52
      log("Name is : " + quote(name.trim()) + ", and Value is : " + quote(value.trim()));
53
    }
54
    else {
55
      log("Línea vacía o sin la estructura esperada. No se puede procesar.");
56
    }
57
  }
58
 
59
  // PRIVADO 
60
  private final Path fFilePath;
61
  private final static Charset ENCODING = StandardCharsets.UTF_8;  
62
 
63
  private static void log(Object aObject){
64
    System.out.println(String.valueOf(aObject));
65
  }
66
 
67
  private String quote(String aText){
68
    String QUOTE = "'";
69
    return QUOTE + aText + QUOTE;
70
  }
71
} 

Si ejecutas el ejemplo se obtendrá:

 Text | 
 
 copy code |
?

1
Name is : 'height', and Value is : '167cm'
2
Name is : 'mass', and Value is : '65kg'
3
Name is : 'disposition', and Value is : '"grumpy"'
4
Name is : 'this is the name', and Value is : 'this is the value'
5
Done.

 

Share Button
Santiago Gonzalez

Sobre 

Santy es uno de los creadores y desarrolladores que componen Developando. Además es profesor en el Master Business Entrepreneurship de la Universidad Complutense de Madrid.

Si quieres conocer más sobre visita su perfil.

    Find more about me on:
  • googleplus

Deja tu comentario

Loading Disqus Comments ...
Loading Facebook Comments ...