2009-11-01 23 views
25

He leído un archivo en una cadena. El archivo contiene varios nombres, un nombre por línea. Ahora el problema es que quiero esos nombres en una matriz String.¿Cómo leer un archivo en una cadena en java?

Por lo que he escrito el siguiente código:

String [] names = fileString.split("\n"); // fileString is the string representation of the file 

Pero no estoy consiguiendo los resultados deseados y la matriz obtenida después de la división de la cadena es de longitud 1. Esto significa que el "fileString" doesn' t tiene el carácter "\ n" pero el archivo tiene este carácter "\ n".

Entonces, ¿cómo evitar este problema?

+1

¿Por qué quiere mantener el \ n. ¿No puedes simplemente asumir que está allí? –

Respuesta

28

El problema no está en cómo está dividiendo la cadena; ese bit es correcto

Tienes que revisar cómo estás leyendo el archivo en la cadena. Es necesario algo como esto:

private String readFileAsString(String filePath) throws IOException { 
     StringBuffer fileData = new StringBuffer(); 
     BufferedReader reader = new BufferedReader(
       new FileReader(filePath)); 
     char[] buf = new char[1024]; 
     int numRead=0; 
     while((numRead=reader.read(buf)) != -1){ 
      String readData = String.valueOf(buf, 0, numRead); 
      fileData.append(readData); 
     } 
     reader.close(); 
     return fileData.toString(); 
    } 
+7

Aunque es correcto, tengo una advertencia para cualquiera que vea esto: no usaría este fragmento de código exacto ya que si se lanza IOException, el lector nunca se cierra y puede dar como resultado que se cuelguen FileReaders que nunca se pueden recolectar. nix world significa que eventualmente se te acabarán los identificadores de archivos y tu JVM simplemente se bloqueará. – Esko

+4

Otro problema es que 'FileReader' retoma implícitamente el juego de caracteres que sea el predeterminado. También el intermedio 'String' es innecesario. –

8

Se podía leer su archivo en un List en lugar de un String y luego convertir a una matriz:

//Setup a BufferedReader here  
List<String> list = new ArrayList<String>(); 
String line = reader.readLine(); 
while (line != null) { 
    list.add(line); 
    line = reader.readLine(); 
} 
String[] arr = list.toArray(new String[0]); 
+2

O incluso dejarlo como una matriz. –

+2

o tal vez dejar el archivo solo por completo – Blub

1

siempre uso esta manera:

String content = ""; 
String line; 
BufferedReader reader = new BufferedReader(new FileReader(...)); 
while ((line = reader.readLine()) != null) 
{ 
    content += "\n" + line; 
} 
// Cut of the first newline; 
content = content.substring(1); 
// Close the reader 
reader.close(); 
+4

FYI: ¿Sueles leer archivos pequeños con ese código? Hubiera esperado un golpe de rendimiento significativo con toda esa concatenación de cadenas ... No quiero ser negativo, solo tengo curiosidad. –

+0

Ehmm, sí ... ¿Este método está en desuso? Oh, ¿qué quiere decir FYI? –

+1

FYI = Para su información, uno de los muchos acrónimos comunes utilizados en la Web. – Esko

43

¿Qué hay de usar Apache Commons (Commons IO y Commons Lang)?

String[] lines = StringUtils.split(FileUtils.readFileToString(new File("...")), '\n'); 
+1

+1 - intercambia una línea de código para una dependencia de Apache Commons IO y Lang. – duffymo

+2

Tenga en cuenta que esto es ahora FileUtils.readFileToString – pimlottc

5

No hay un método incorporado en Java que pueda leer un archivo completo. Por lo que tiene las siguientes opciones:

  • utilizar un método de biblioteca no estándar, como Apache Commons, véase el ejemplo de código en la respuesta de romaintaz.
  • Circule alrededor de algún método read (por ejemplo, FileInputStream.read, que lee bytes, o FileReader.read, que lee caracteres, ambos leen a una matriz preasignada). Ambas clases usan llamadas al sistema, por lo que tendrá que acelerarlas con el método de confirmación (BufferedInputStream o BufferedReader) si está leyendo solo una pequeña cantidad de datos (por ejemplo, menos de 4096 bytes) a la vez.
  • Loop around BufferedReader.readLine. Existe un problema fundamental que descarta la información de si había un '\n' al final del archivo, por ejemplo, no puede distinguir un archivo vacío de un archivo que contiene solo una nueva línea.

que haría uso de este código:

// charsetName can be null to use the default charset. 
public static String readFileAsString(String fileName, String charsetName) 
    throws java.io.IOException { 
    java.io.InputStream is = new java.io.FileInputStream(fileName); 
    try { 
    final int bufsize = 4096; 
    int available = is.available(); 
    byte[] data = new byte[available < bufsize ? bufsize : available]; 
    int used = 0; 
    while (true) { 
     if (data.length - used < bufsize) { 
     byte[] newData = new byte[data.length << 1]; 
     System.arraycopy(data, 0, newData, 0, used); 
     data = newData; 
     } 
     int got = is.read(data, used, data.length - used); 
     if (got <= 0) break; 
     used += got; 
    } 
    return charsetName != null ? new String(data, 0, used, charsetName) 
           : new String(data, 0, used); 
    } finally { 
    is.close(); 
    } 
} 

El código anterior tiene las siguientes ventajas:

  • Es correcto: se lee todo el archivo, no descartando cualquier byte.
  • Le permite especificar el juego de caracteres (codificación) que utiliza el archivo.
  • Es rápido (no importa cuántas líneas nuevas contenga el archivo).
  • No desperdicia memoria (no importa cuántas líneas nuevas contenga el archivo).
17

Como sugiere Garrett Rowe and Stan James puede utilizar java.util.Scanner:

try (Scanner s = new Scanner(file).useDelimiter("\\Z")) { 
    String contents = s.next(); 
} 

o

try (Scanner s = new Scanner(file).useDelimiter("\\n")) { 
    while(s.hasNext()) { 
    String line = s.next(); 
    } 
} 

Este código no tiene dependencias externas. Aquí está un ejemplo de cómo utilizar java.util.Scanner con recursos correcta y el control de errores:

import java.io.File; 
import java.io.FileNotFoundException; 
import java.util.Scanner; 
import java.util.Iterator; 

class TestScanner { 
    public static void main(String[] args) 
    throws FileNotFoundException { 
    File file = new File(args[0]); 

    System.out.println(getFileContents(file)); 

    processFileLines(file, new LineProcessor() { 
     @Override 
     public void process(int lineNumber, String lineContents) { 
     System.out.println(lineNumber + ": " + lineContents); 
     } 
    }); 
    } 

    static String getFileContents(File file) 
    throws FileNotFoundException { 
    try (Scanner s = new Scanner(file).useDelimiter("\\Z")) { 
     return s.next(); 
    } 
    } 

    static void processFileLines(File file, LineProcessor lineProcessor) 
    throws FileNotFoundException { 
    try (Scanner s = new Scanner(file).useDelimiter("\\n")) { 
     for (int lineNumber = 1; s.hasNext(); ++lineNumber) { 
     lineProcessor.process(lineNumber, s.next()); 
     } 
    } 
    } 

    static interface LineProcessor { 
    void process(int lineNumber, String lineContents); 
    } 
} 
+1

+1 para la solución nativa más simple. Por cierto, no olvides evitar la pérdida de recursos usando 'scanner.close();' – mmdemirbas

+1

@mmdemirbas, OK He agregado un ejemplo completo con recursos y manejo de errores. Gracias por la advertencia. –

3
FileReader fr=new FileReader(filename); 
BufferedReader br=new BufferedReader(fr); 
String strline; 
String arr[]=new String[10];//10 is the no. of strings 
while((strline=br.readLine())!=null) 
{ 
arr[i++]=strline; 
} 
1

La solución más simple para la lectura de una línea de archivo de texto por línea y poner los resultados en una matriz de cadenas sin utilizar terceros bibliotecas sería la siguiente:

ArrayList<String> names = new ArrayList<String>(); 
Scanner scanner = new Scanner(new File("names.txt")); 
while(scanner.hasNextLine()) { 
    names.add(scanner.nextLine()); 
} 
scanner.close(); 
String[] namesArr = (String[]) names.toArray(); 
0

un simple (sin bucles), pero menos correcta manera, es leer todo a una matriz de bytes:

FileInputStream is = new FileInputStream(file); 
byte[] b = new byte[(int) file.length()]; 
is.read(b, 0, (int) file.length()); 
String contents = new String(b); 

También tenga en cuenta que esto tiene graves problemas de rendimiento.

0

Si solo tiene InputStream, puede usar InputStreamReader.

SmbFileInputStream in = new SmbFileInputStream("smb://host/dir/file.ext"); 
InputStreamReader r=new InputStreamReader(in); 
char buf[] = new char[5000]; 
int count=r.read(buf); 
String s=String.valueOf(buf, 0, count); 

Puede agregar ciclo y StringBuffer si es necesario.

0

También puede utilizar java.nio.file.Files para leer un archivo completo en una lista de cadenas a continuación, se puede convertir en una matriz, etc. Suponiendo una variable de cadena denominado rutaArchivo, los siguientes 2 líneas que van a hacer:

List<String> strList = Files.readAllLines(Paths.get(filePath), Charset.defaultCharset()); 
String[] strarray = strList.toArray(new String[0]); 
4

En particular, me encanta este usando el paquete java.nio.file que también se describe here.

String content = new String(Files.readAllBytes(Paths.get("/path/to/file"))); 

Cool huhhh!

0

Usted puede intentar Cactoos:

import org.cactoos.io.TextOf; 
import java.io.File; 
new TextOf(new File("a.txt")).asString().split("\n") 
Cuestiones relacionadas