2010-12-15 33 views
11

tengo este código en Java:leer una línea de texto de un flujo de entrada en Java manteniendo el carácter (s)-terminación de línea

InputStreamReader isr = new InputStreamReader(getInputStream()); 
BufferedReader ir = new BufferedReader(isr); 
String line; 
while ((line = ir.readLine()) != null) { 
//do stuff with "line" 
} 

Si el flujo de entrada contiene lo siguiente: "hola \ nhey \ Ryo \ r \ Ngood días", entonces la variable de línea estaría siguiendo en cada iteración:

  1. hola
  2. bueno
  3. yo
  4. buena-da Y

quiero leer una línea a la vez, pero quiero mantener el carácter (s)-terminación de línea:

  1. hola \ n
  2. bueno \ r
  3. años \ r \ n
  4. buenos días

¿Cómo puedo hacer esto? ¿Hay clases preparadas que pueda usar?

-

Actualización:

Aquí es lo que estoy tratando de hacer y por lo que necesita para mantener el carácter de fin de línea (y por qué el carácter EOL puede ser diferente).

Estoy leyendo una solicitud POST. Consisten en mensajes de texto puros donde las líneas siempre terminan con \ r \ n (según la especificación estándar). Sin embargo, la solicitud POST puede contener datos binarios, que pueden contener bytes que parecen caracteres de terminación para los objetos de Java Reader.

En mi ejemplo, se está cargando una imagen. Los datos de la imagen se envían en una sola línea. Sin embargo, sin embargo, los datos binarios de la imagen contienen bytes que el LECTOR interpretaría como "\ n", "\ r" o algunas veces "\ r \ n" si esos dos bytes están uno al lado del otro.

Tengo que leer la solicitud POST una línea a la vez porque así es como funciona. Supongo que PODRÍA leer todo y luego analizar todo. Pero eso no es eficiente, especialmente si se está cargando un archivo de gran tamaño (digamos 1024 MiB).

+0

Si no puede encontrar una solución mejor, puede implementar su 'readLine' utilizando' BufferedReader.read() 'en un bucle' while'. – pts

+0

Tenía la esperanza de que esto muy básico ya estuviera hecho, uno hubiera pensado que podrían haberlo hecho para que el método readLine() de BufferedReader aceptara un booleano, si es verdadero, también incluiría el (los) carácter (es) de separador de línea y si es falso, se comportaría como lo hace en este momento. – Mike

+0

¿Es importante mantener el carácter final particular? Porque lo primero que pensé fue simplemente agregar un '\ n' a la línea – TheLQ

Respuesta

4

Si desea leer una petición HTTP POST, recomiendo el uso de BufferedInputStream.read() (no BufferedReader!) Directamente (sin readLine -como abstracciones intermedios), prestando atención a todos los detalles manualmente, incluyendo el manejo de CR y LF según el HTTP RFC.

Aquí está mi respuesta a su pregunta más específica (cómo implementar exactamente eso readLine). Esto podría no ser la solución más rápida, pero es tiempo de complejidad es óptima, y ​​funciona:

import java.io.BufferedReader; 
import java.io.IOException; 
public class LineReader { 
    private int i = -2; 
    private BufferedReader br; 
    public OriginalLineReader(BufferedReader br) { this.br = br; } 
    public String readLine() throws IOException { 
    if (i == -2) i = br.read(); 
    if (i < 0) return null; 
    StringBuilder sb = new StringBuilder(); 
    sb.append((char)i); 
    if (i != '\r' && i != '\n') { 
     while (0 <= (i = br.read()) && i != '\r' && i != '\n') { 
     sb.append((char)i); 
     } 
     if (i < 0) return sb.toString(); 
     sb.append((char)i); 
    } 
    if (i == '\r') { 
     i = br.read(); 
     if (i != '\n') return sb.toString(); 
     sb.append((char)'\n'); 
    } 
    i = -2; 
    return sb.toString(); 
    } 
} 

que no encontrará tal readLine construido en Java. Es probable que encuentre similares, pero no coincidan exactamente con readLine s en un archivo de terceros .jar. Mi recomendación es solo usar la de arriba, si realmente necesita esa característica.

+0

Ese es exactamente el tipo de código que esperaba no tener que escribir yo mismo, ¡muchas gracias! Aún así creo que debería haber estado en Java por defecto. – Mike

+1

Cuando se diseñaron esas API java, la codificación de fin de línea específica de la plataforma era aún más insegura de lo que es ahora. Están tratando de aislarte de tener que lidiar con \ n vs \ r vs \ r \ n frente a Dios solo sabe qué * Nixes propietarios estaban usando en 1993, al proporcionar readLine y writeLine y manejarlo internamente. – Affe

+0

Affe: Creo que hay un pequeño error de hecho en su razonamiento. Mi comprensión general es que todos los sistemas Unix siempre tenían ''\ n'' (que es igual a' 10') como terminador de línea. – pts

Cuestiones relacionadas