Las citas rizadas causan que Java Scanner hasNextLine () sea falso, ¿por qué?

He estado teniendo un problema para que el explorador java.util.Scanner lea un archivo de texto que guardé en el Bloc de notas, aunque funciona bien con otros. Básicamente, cuando intenta leer el archivo problemático, aparece con las manos completamente vacías: hasNextLine () es falso, el búfer está vacío, etc. Lo reduje al hecho de que ni siquiera leerá la primera línea si existe. es una cita rizadaen cualquier sitio en el archivo. No se lanzan excepciones. Tenga en cuenta que un BufferedReader en el mismo archivo no tiene ningún problema.

try {        
    int count = 0;
    Scanner scanner = new Scanner(new File("C:/myfile.txt"));

    while (scanner.hasNextLine()) {
        count++;
        scanner.nextLine();
    }

    scanner.close();
    System.out.print(count);

    count = 0;
    BufferedReader reader = new BufferedReader(new FileReader("C:/myfile.txt"));

    while (reader.readLine() != null) {
        count++;
    }

    reader.close();
    System.out.print(count);
}
catch(IOException e) {
    e.printStackTrace();
}

El código anterior, que lee un archivo que contiene nada más que una sola cita, imprime "01". Las búsquedas en Google me llevaron a probar esto:

Scanner scanner = new Scanner(new File("C:/myfile.txt"), "ISO-8859-1");

Esto lo hace funcionar (es decir, imprime "11"). También noté que si voy al Bloc de notas y hago Guardar como ... la codificación predeterminada en la parte inferior es "ANSI". Si cambio esto a "UTF-8" y guardo el archivo, entonces el escáner (sin una codificación) también funciona. Si le digo al escáner "UTF-8", entonces es comprensible que solo funcione si lo guardo como UTF-8, pero "ISO-8859-1" parece hacer que funcione incluso si lo guardo como "ANSI".

Entonces, sé que tiene algo que ver con la codificación de archivos, pero el problema es que no entiendo nada sobre la codificación de archivos. Mi conocimiento de lo que significa "ISO-8859-1" es extremadamente vago; ¿Por qué eso hace que funcione sin importar cómo guarde el archivo? ¿Por qué BufferedReader funciona independientemente?

EDITAR:

¡Los enlaces / comentarios a continuación realmente ayudaron a señalarme en la dirección correcta! Creo que lo tengo resuelto.

En primer lugar, en el Bloc de notas:

"ANSI" es CP1252"Unicode" es UTF-16LE"UTF-8" es ... bueno, UTF-8

En hexadecimal, un apóstrofe rizado se representa como:

CP1252: 92UTF-16LE: 1920UTF-8: E2 80 99

La codificación predeterminada que utiliza Java en mi sistema, según Charset.defaultCharset (), es UTF-8. Entonces, cuando guardé el archivo en UTF-8, el escáner sabía qué esperar. Cuando guardé el archivo en CP1252, sin embargo, se ahogó una vez que golpeó ese "92", porque no es una forma válida de representar un carácter en esa codificación. Funciona bien siempre y cuando no haya tales caracteres en el archivo; el hex para "hola mundo" es el mismo tanto en CP1252 como en UTF-8 y no causa ningún problema.

UTF-8 no funciona con un archivo UTF-16, porque no sabe qué hacer con la marca de orden de bytes ("FFFE"), independientemente de qué caracteres se encuentren en el archivo.

Por otro lado, cuando configuro el escáner en CP1252 o ISO-8859-1, es mucho más tolerante. No necesariamente interpreta a los personajes.correctamente, fíjese, pero no hay nada que le impida reconocer líneas en el archivo y recorrerlas.

En cuanto a por qué el Escáner tiene un problema, pero el FileReader / BufferedReader no lo tiene, voy a adivinar que es porque el escáner necesita tokenizar el archivo, es decir. interpreta los caracteres para que puedan identificar los espacios en blanco y otros patrones, para que se ahogue cuando hay algo irreconocible. El lector no necesita hacer eso. Todo lo que necesita identificar son los saltos de línea.

Respuestas a la pregunta(3)

Su respuesta a la pregunta