Lee una línea de texto. Se considera que una línea termina con un salto de línea ('\n'), un retorno de carro ('\r') o un retorno de carro seguido inmediatamente por un salto de línea.------ javadoc 1.8
Entonces tengo un archivo de texto como este:
the first line the second linenota: el último carácter de la segunda línea es 'e', es decir, no existe retorno de carro.
entonces aquí está mi código de demostración.
public void process() throws IOException{ BufferedReader br = new BufferedReader(new FileReader("demo.txt")); String line; while((line=br.readLine())!=null){ System.out.println(line); } br.close(); }la salida real:
the first line the second line entonces mi pregunta es por qué el método readLine puede obtener la segunda línea porque no tiene un separador de línea (\n o \r o \n\r).
Sé que existe un fin de archivo (EOF) , pero parecía que el javadoc no dice que el EOF también es el separador de línea explícitamente.
Si uso Scanner en lugar de BufferedReader, el código es el siguiente:
public void testScan() throws IOException{ Scanner scan = new Scanner(new FileInputStream("demo.txt")); String line; while((line=scan.nextLine())!=null){ System.out.println(line); } scan.close(); }entonces la salida seria:
the first line the second line Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1540) at com.demo.Demo.testScan(Demo.java:39) at com.demo.Demo.main(Demo.java:49)Porque está programado de esa manera.
Realmente, es lo que quiere el usuario del método. Si a la última línea le falta un separador de línea al final, se leerá hasta EOF para que no se pierdan datos. No desea perder una línea completa debido a la falta de un separador de línea.
Prácticamente todas las funciones similares funcionan de la misma manera. Por ejemplo, si está mirando la función fgets() en la biblioteca C, también funcionará de esa manera. También lo hace f.readline() en Python.
Editar: el escáner también funciona de manera similar, pero la diferencia es que un escáner arroja una excepción, mientras que BufferedReader devuelve un valor nulo cuando se han leído todas las líneas.
parecía que el javadoc no le dice al EOF que también es el separador de línea explícitamente.
Creo que estás confundiendo el separador de línea con el terminador de línea .
Un separador de línea simplemente separa las líneas entre sí. Dado un separador de línea ; e ingrese one;two;three , obtendría las líneas one , two y three . Sin embargo, dado el mismo carácter y entrada pero ; siendo un terminador de línea, obtendría las líneas one y two ya que la última línea no está terminada.
En la práctica, esto significa que si EOF realmente fuera un separador de línea, obtendría datos adicionales. Como EOF técnicamente no es un carácter sino una condición de que el archivo ha finalizado, tener EOF como separador de línea tendría consecuencias descabelladas.
Sin embargo, dado el javadoc :
Lee una línea de texto. Se considera que una línea termina con un salto de línea ('\n'), un retorno de carro ('\r') o un retorno de carro seguido inmediatamente por un salto de línea.
Creo que la terminología también se usa mal allí. O el javadoc debería hablar sobre la separación en lugar de la terminación, debería mencionar EOF como una de las condiciones que terminan la línea o la implementación no debería tratar la última como una línea separada.
De Wikipedia :
Dos formas de ver las líneas nuevas, ambas autoconsistentes, son que las líneas nuevas separan líneas o terminan líneas. Si una nueva línea se considera un separador, no habrá nueva línea después de la última línea de un archivo. Algunos programas tienen problemas para procesar la última línea de un archivo si no termina con una nueva línea. Por otro lado, los programas que esperan que se use una nueva línea como separador interpretarán una nueva línea final como el comienzo de una nueva línea (vacía). Por el contrario, si una nueva línea se considera un terminador, se espera que todas las líneas de texto, incluida la última, terminen con una nueva línea. Si la secuencia de caracteres final en un archivo de texto no es una nueva línea, la línea final del archivo se puede considerar como una línea de texto incorrecta o incompleta, o se puede considerar que el archivo está truncado incorrectamente.
Entonces parece que readLine() tiene estos mezclados.
IMO readLine() javadoc debería decir algo como:
Se considera que una línea termina al final del archivo o por un salto de línea ('\n'), un retorno de carro ('\r') o un retorno de carro seguido inmediatamente por un salto de línea.
o para una expresión un poco más vaga, similar a lo que dice Scanner.nextLine() :
Este método devuelve la [..] línea actual, excluyendo cualquier separador de línea al final
Con la adición de que devolverá null cuando el final del archivo sea la única entrada que quede.