2010-10-04 32 views
6

Una de las líneas en un archivo java que intento entender es la siguiente.Leyendo un archivo usando el escáner Java

return new Scanner(file).useDelimiter("\\Z").next(); 

El archivo se espera que regrese hasta "El final de la entrada, pero para el terminador final, si los hay" documentación según java.util.regex.Pattern. Pero lo que sucede es que devuelve solo los primeros 1024 caracteres del archivo. ¿Es esto una limitación impuesta por el matcheador Patrón de expresiones regulares? ¿Se puede superar esto? Actualmente estoy usando un lector de archivos. Pero me gustaría saber el motivo de este comportamiento.

+0

¡NUNCA use Scanner! Realmente, tendrás tantos problemas. –

+8

@Martijn Courteaux: ¿le importa proporcionar siquiera la más mínima pista sobre por qué Scanner es malo? – whaley

Respuesta

2

trate de envolver el objeto file en un FileInputStream

+0

¿Podría [editar] su respuesta para explicar por qué esto ayudaría y cuál es el problema subyacente? Tal como está, esto es poco más que un comentario. –

5

Yo mismo no pude reproducir esto. Pero creo que puedo arrojar luz sobre lo que está pasando.

Internamente, el escáner utiliza un búfer de caracteres de 1024 caracteres. El Escáner leerá de forma predeterminada, de ser posible, 1024 caracteres Leíbles y luego aplicará el patrón.

El problema está en su patrón ... siempre coincidirá con el final de la entrada, pero eso no significa el final de su flujo/datos de entrada. Cuando Java aplica su patrón a los datos almacenados en el búfer, intenta encontrar la primera aparición del final de la entrada. Como 1024 caracteres están en el búfer, el motor que hace juego llama a la posición 1024 la primera coincidencia del delimitador y todo antes de que se devuelva como el primer token.

No creo que el anclaje de fin de entrada sea válida para su uso en el escáner por ese motivo. Podría estar leyendo de una corriente infinita, después de todo.

+0

Hola Mark, creo que es una razón correcta para que el escáner no funcione. Estoy votando la respuesta. La forma de hacerlo funcionar es la correcta. Gracias por su respuesta. – Sharmila

1

Scanner está destinado a leer múltiples primitivas de un archivo. Realmente no está destinado a leer un archivo completo.

Si no desea incluir bibliotecas de terceros, es mejor bucle durante un BufferedReader que envuelve un FileReader/InputStreamReader para el texto o en un bucle FileInputStream para datos binarios.

Si estás bien utilizando una biblioteca de terceros, Apache commons-io tiene una clase FileUtils que contiene los métodos estáticos y readFileToStringreadLines para el texto y readFileToByteArray para datos binarios ..

0

Puede utilizar la clase escáner, acaba de especificar un conjunto de caracteres al abrir el escáner, es decir:

Scanner sc = new Scanner(file, "ISO-8859-1"); 

Java convierte bytes leídos desde el archivo en caracteres utilizando el juego de caracteres especificado, que es el que viene por defecto (de sistema operativo subyacente) si se le da nada (source) Todavía no tengo claro por qué Scanner solo lee 1024 bytes con el predeterminado, mientras que con otro alcanza el final de un archivo. De todos modos, funciona bien!