Java: cómo leer un archivo de texto

81

Quiero leer un archivo de texto que contenga valores separados por espacios. Los valores son números enteros. ¿Cómo puedo leerlo y ponerlo en una lista de matrices?

A continuación, se muestra un ejemplo del contenido del archivo de texto:

1 62 4 55 5 6 77

Quiero tenerlo en una lista de arrays como [1, 62, 4, 55, 5, 6, 77]. ¿Cómo puedo hacerlo en Java?

aks
fuente

Respuestas:

170

Puede usar Files#readAllLines()para obtener todas las líneas de un archivo de texto en un archivo List<String>.

for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    // ...
}

Tutorial: E / S básica> E / S de archivo> Leer, escribir y crear archivos de texto


Puede utilizar String#split()para dividir Stringen partes basándose en una expresión regular.

for (String part : line.split("\\s+")) {
    // ...
}

Tutorial: Números y cadenas> Cadenas> Manipulación de caracteres en una cadena


Puede usar Integer#valueOf()para convertir un Stringen un Integer.

Integer i = Integer.valueOf(part);

Tutorial: Números y cadenas> Cadenas> Conversión entre números y cadenas


Puede usar List#add()para agregar un elemento a un List.

numbers.add(i);

Tutorial: Interfaces> La interfaz de lista


Entonces, en pocas palabras (asumiendo que el archivo no tiene líneas vacías ni espacios en blanco finales / iniciales).

List<Integer> numbers = new ArrayList<>();
for (String line : Files.readAllLines(Paths.get("/path/to/file.txt"))) {
    for (String part : line.split("\\s+")) {
        Integer i = Integer.valueOf(part);
        numbers.add(i);
    }
}

Si ya está en Java 8, entonces puede incluso usar Stream API para esto, comenzando con Files#lines().

List<Integer> numbers = Files.lines(Paths.get("/path/to/test.txt"))
    .map(line -> line.split("\\s+")).flatMap(Arrays::stream)
    .map(Integer::valueOf)
    .collect(Collectors.toList());

Tutorial: procesamiento de datos con secuencias de Java 8

BalusC
fuente
1
Tenga en cuenta que hay mejores formas de hacer esto en Java 7 y 8: stackoverflow.com/questions/4716503/…
Alex Beardsley
34

Java 1.5 introdujo la clase Scanner para manejar la entrada de archivos y flujos.

Se usa para obtener números enteros de un archivo y se vería así:

List<Integer> integers = new ArrayList<Integer>();
Scanner fileScanner = new Scanner(new File("c:\\file.txt"));
while (fileScanner.hasNextInt()){
   integers.add(fileScanner.nextInt());
}

Sin embargo, consulte la API. Hay muchas más opciones para tratar con diferentes tipos de fuentes de entrada, diferentes delimitadores y diferentes tipos de datos.

tschaible
fuente
2
esto es mucho más fácil de recordar que la combinación de lector, io
búfer
18

Este código de ejemplo le muestra cómo leer un archivo en Java.

import java.io.*;

/**
 * This example code shows you how to read file in Java
 *
 * IN MY CASE RAILWAY IS MY TEXT FILE WHICH I WANT TO DISPLAY YOU CHANGE WITH YOUR   OWN      
 */

 public class ReadFileExample 
 {
    public static void main(String[] args) 
    {
       System.out.println("Reading File from Java code");
       //Name of the file
       String fileName="RAILWAY.txt";
       try{

          //Create object of FileReader
          FileReader inputFile = new FileReader(fileName);

          //Instantiate the BufferedReader Class
          BufferedReader bufferReader = new BufferedReader(inputFile);

          //Variable to hold the one line data
          String line;

          // Read file line by line and print on the console
          while ((line = bufferReader.readLine()) != null)   {
            System.out.println(line);
          }
          //Close the buffer reader
          bufferReader.close();
       }catch(Exception e){
          System.out.println("Error while reading file line by line:" + e.getMessage());                      
       }

     }
  }
Sajjad Khan
fuente
10

Mire este ejemplo e intente hacer el suyo:

import java.io.*;

public class ReadFile {

    public static void main(String[] args){
        String string = "";
        String file = "textFile.txt";

        // Reading
        try{
            InputStream ips = new FileInputStream(file);
            InputStreamReader ipsr = new InputStreamReader(ips);
            BufferedReader br = new BufferedReader(ipsr);
            String line;
            while ((line = br.readLine()) != null){
                System.out.println(line);
                string += line + "\n";
            }
            br.close();
        }
        catch (Exception e){
            System.out.println(e.toString());
        }

        // Writing
        try {
            FileWriter fw = new FileWriter (file);
            BufferedWriter bw = new BufferedWriter (fw);
            PrintWriter fileOut = new PrintWriter (bw);
                fileOut.println (string+"\n test of read and write !!");
            fileOut.close();
            System.out.println("the file " + file + " is created!");
        }
        catch (Exception e){
            System.out.println(e.toString());
        }
    }
}
Eddinho
fuente
5

Solo por diversión, esto es lo que probablemente haría en un proyecto real, donde ya estoy usando todas mis bibliotecas favoritas (en este caso , Guava , antes conocida como Colecciones de Google ).

String text = Files.toString(new File("textfile.txt"), Charsets.UTF_8);
List<Integer> list = Lists.newArrayList();
for (String s : text.split("\\s")) {
    list.add(Integer.valueOf(s));
}

Beneficio: No hay mucho código propio que mantener (en contraste, por ejemplo, con este ). Editar : ¡Aunque vale la pena señalar que en este caso la solución Scanner de tschaible no tiene más código!

Inconveniente: obviamente, es posible que no desee agregar nuevas dependencias de biblioteca solo para esto. (Por otra parte, sería una tontería no utilizar Guava en sus proyectos. ;-)

Jonik
fuente
Por supuesto, también se podría usar transform () y una función de las colecciones de Google en lugar del bucle, pero en mi humilde opinión, sería menos legible y ni siquiera más corto.
Jonik
4

Use Apache Commons (IO y Lang) para cosas simples / comunes como esta.

Importaciones:

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ArrayUtils;

Código:

String contents = FileUtils.readFileToString(new File("path/to/your/file.txt"));
String[] array = ArrayUtils.toArray(contents.split(" "));

Hecho.

Chris
fuente
2

Usando Java 7 para leer archivos con NIO.2

Importa estos paquetes:

import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Este es el proceso para leer un archivo:

Path file = Paths.get("C:\\Java\\file.txt");

if(Files.exists(file) && Files.isReadable(file)) {

    try {
        // File reader
        BufferedReader reader = Files.newBufferedReader(file, Charset.defaultCharset());

        String line;
        // read each line
        while((line = reader.readLine()) != null) {
            System.out.println(line);
            // tokenize each number
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            while (tokenizer.hasMoreElements()) {
                // parse each integer in file
                int element = Integer.parseInt(tokenizer.nextToken());
            }
        }
        reader.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Para leer todas las líneas de un archivo a la vez:

Path file = Paths.get("C:\\Java\\file.txt");
List<String> lines = Files.readAllLines(file, StandardCharsets.UTF_8);
user2601995
fuente
1

Todas las respuestas dadas hasta ahora implican leer el archivo línea por línea, tomar la línea como a String, y luego procesar el String.

No hay duda de que este es el enfoque más fácil de entender, y si el archivo es bastante corto (digamos, decenas de miles de líneas), también será aceptable en términos de eficiencia. Pero si el archivo es largo , es una forma muy ineficiente de hacerlo, por dos razones:

  1. Cada personaje se procesa dos veces, una al construir Stringy otra al procesarlo.
  2. El recolector de basura no será su amigo si hay muchas líneas en el archivo. Estás construyendo una nueva Stringpara cada línea y luego la tiras cuando pasas a la siguiente línea. El recolector de basura eventualmente tendrá que deshacerse de todos estos Stringobjetos que usted ya no quiere. Alguien tiene que limpiar después de ti.

Si le importa la velocidad, es mucho mejor leer un bloque de datos y luego procesarlo byte por byte en lugar de línea por línea. Cada vez que llega al final de un número, lo agrega al Listque está construyendo.

Saldrá algo como esto:

private List<Integer> readIntegers(File file) throws IOException {
    List<Integer> result = new ArrayList<>();
    RandomAccessFile raf = new RandomAccessFile(file, "r");
    byte buf[] = new byte[16 * 1024];
    final FileChannel ch = raf.getChannel();
    int fileLength = (int) ch.size();
    final MappedByteBuffer mb = ch.map(FileChannel.MapMode.READ_ONLY, 0,
            fileLength);
    int acc = 0;
    while (mb.hasRemaining()) {
        int len = Math.min(mb.remaining(), buf.length);
        mb.get(buf, 0, len);
        for (int i = 0; i < len; i++)
            if ((buf[i] >= 48) && (buf[i] <= 57))
                acc = acc * 10 + buf[i] - 48;
            else {
                result.add(acc);
                acc = 0;
            }
    }
    ch.close();
    raf.close();
    return result;
}

El código anterior asume que esto es ASCII (aunque podría modificarse fácilmente para otras codificaciones) y que cualquier cosa que no sea un dígito (en particular, un espacio o una nueva línea) representa un límite entre dígitos. También asume que el archivo termina con un no dígito (en la práctica, que la última línea termina con una nueva línea), aunque, nuevamente, podría modificarse para tratar el caso donde no lo hace.

Es mucho, mucho más rápido que cualquiera de los Stringenfoques basados ​​también en respuestas a esta pregunta. Hay una investigación detallada de un tema muy similar en esta pregunta . Verá allí que existe la posibilidad de mejorarlo aún más si desea bajar por la línea de subprocesos múltiples.

seguridad quiástica
fuente
0

lee el archivo y luego haz lo que quieras java8 Files.lines (Paths.get ("c: //lines.txt")). collect (Collectors.toList ());

Ran Adler
fuente