2012-02-13 19 views

Respuesta

41

que puede usar:

BufferedReader bufReader = new BufferedReader(new StringReader(textContent)); 

Y utilizar el método readLine():

String line=null; 
while((line=bufReader.readLine()) != null) 
{ 

} 
+0

Gracias por la respuesta. ¿Esta solución proporciona un mejor rendimiento? Noté que esta solución usa el objeto ** 3 **. Quiero limitar la creación de un objeto para tener suficiente memoria, ¿entonces 'BufferedReader' y' StringReader' son más livianos que una matriz String? –

+0

Como dice javadoc para BufferedReader, el uso de dicha clase es un medio válido para envolver métodos de lectura costosos para lecturas rentables. Consulta http://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html –

6

Usted podría utilizar String.indexOf()/String.substring()

String separator = System.getProperty("line.separator"); 
int index = textContent.indexOf(separator); 

while (index > 0) 
{ 
    int nextIndex = textContent.indexOf(separator, index + separator.length()); 
    String line = textContent.substring(index + separator.length(), nextIndex); 

    // do something with line. 
} 
3

¿Qué pasa con la clase java.util.Scanner?

En resumen:

Un escáner de texto simple que puede analizar los tipos y cadenas primitivas usando expresiones regulares.

Un escáner divide su entrada en tokens utilizando un patrón de delimitador, que por defecto coincide con el espacio en blanco. Los tokens resultantes pueden entonces ser convierten en valores de diferentes tipos utilizando los diversos métodos próximos.

y en la nota para su escenario:

El escáner también puede utilizar delimitadores distintos espacios en blanco. Este ejemplo lee varios artículos a partir de una cadena:

 String input = "1 fish 2 fish red fish blue fish"; 
    Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*"); 
    System.out.println(s.nextInt()); 
    System.out.println(s.nextInt()); 
    System.out.println(s.next()); 
    System.out.println(s.next()); 
    s.close(); 
1

uso BufferedReader con el argumento StringReader. BufferedReader tiene un método readLine() para que pueda leer su secuencia línea por línea.

StringReader reader = new StringReader(myBigTextString); 
    BufferedReader br = new BufferedReader(reader); 
    String line; 
    while((line=br.readLine())!=null) 
    { 
     //do what you want 
    } 
+1

@ alain.janinm, cuando mantienes una matriz de líneas divididas esa matriz requiere mucha memoria como dices . En este caso, todas las líneas de su texto no se cargan en la memoria. BufferedReader solo recuerda el último punto de lectura y cuando llamas al método readLine() simplemente lee la siguiente línea de tu cadena (con la ayuda de StringReader). Por lo tanto, en cada iteración, solo tiene una línea de texto en la memoria (en la variable 'línea') en lugar de todas las líneas. – shift66

1

Combinar java.io.StringReader y java.io.LineNumberReader

+0

Gracias por la respuesta. otro 'BufferedReader' propuesto. ¿Cuáles son las ventajas de 'java.io.LineNumberReader'? –

+0

En realidad, simplemente no me di cuenta de que BufferedReader también tiene implementado el método readLine(). –

+0

Para futuros lectores: LineNumberReader amplía BufferedReader, por lo que LineNumberReader es un reemplazo directo para BufferedReader con el comportamiento adicional de rastrear el número de línea de la línea que acaba de leer. Ver http://docs.oracle.com/javase/8/docs/api/java/io/LineNumberReader.html. – MonkeyWithDarts

5

Splitter obras de guayaba también. Especialmente en lo que se puede quitar líneas en blanco

Splitter splitter = Splitter.on(System.getProperty("line.separator")) 
          .trimResults() 
          .omitEmptyStrings(); 
for (String line : splitter.split(input)){ 
    // do work here 
} 
+2

Del código fuente de guava: '' 'Splitter.on (Pattern.compile (" \ r? \ N ")). Split (wholeFile)' '' –

+0

Más precisamente, está en el Javadoc para 'Splitter # on': https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/base/Splitter.html#on-java.util.regex.Pattern- – simon04

12

Para agregar la forma de Java 8 a esta pregunta:

Arrays.stream(content.split("\\r?\\n")).forEach(line -> /*do something */) 

de la maldición también puede utilizar System.lineSeparator() para dividir si está seguro de que el archivo está viniendo de la misma plataforma en la que se ejecuta vm.

O aún mejor utilizar la API de flujo aún más agressiv con filtro, mapas y recoger:

String result = Arrays.stream(content.split(System.lineSeparator())) 
        .filter(/* filter for lines you are interested in*/) 
        .map(/*convert string*/) 
        .collect(Collectors.joining(";")); 
+0

probablemente usaría la verdadera versión java8 'System.lineSeparator()' en lugar de la propiedad directamente – xenoterracide

+0

@xenoterracide ¡tienes razón! Cambió la respuesta en consecuencia. – leo

+0

Ha editado accidentalmente la parte 'content' en su segundo ejemplo. – Torque

1

En realidad se puede disputar Scanner a permitir el uso de una normal de for bucle:

import java.util.Scanner; 
public class IterateLines { 
    public static void main(String[] args) { 
     Iterable<String> sc =() -> 
      new Scanner("foo bar\nbaz\n").useDelimiter("\n"); 
     for (String line: sc) { 
      System.out.println(line); 
     } 
    } 
} 

nos da:

$ javac IterateLines.java && java IterateLines 
foo bar 
baz 
+0

Esto dividirá la cadena en espacios y líneas nuevas, que no es lo que la pregunta está buscando. – Zulakis

+0

Gracias @Zulakis - He corregido el código para usar un delimitador explícito. –

Cuestiones relacionadas