Estou lendo um arquivo com o seguinte trecho de código:
Scanner in = new Scanner(new File(fileName));
while (in.hasNextLine()) {
String[] line = in.nextLine().trim().split("[ \t]");
.
.
.
}
Quando abro o arquivo com o vim, algumas linhas começam com o caractere especial seguinte:
mas o código java não pode ler estas linhas. Quando ela atinge essas linhas que acha que é o fim do arquivo e hasNextLine () retorna falso !!
EDIT: este é o hexadecimal da linha mencionada (problemático):
0000000: e280 9c20 302e 3230 3133 3220 302e 3231 ... 0,20132 0,21 0000010: 3431 392d 302e 3034 0a 419-,04.
@VGR acertou.
tl; dr: Use Scanner in = new Scanner(new File(fileName), "ISO-8859-1");
O que parece estar acontecendo é que:
- Seu arquivo não é válido UTF-8 devido a esse personagem 0x9C solitário.
- O scanner está lendo o arquivo como UTF-8, porque essa é a padrão do sistema
- As bibliotecas subjacentes jogar um
MalformedInputException
- As capturas de scanner e esconde-(uma decisão de projeto bem intencionados, mas mal orientado)
- Ele começa a informar que não tem mais linhas
- Você não vai saber errado ido de nada menos que você realmente pedir o Scanner
Aqui está uma MCVE:
import java.io.*;
import java.util.*;
class Test {
public static void main(String[] args) throws Exception {
Scanner in = new Scanner(new File(args[0]), args[1]);
while (in.hasNextLine()) {
String line = in.nextLine();
System.out.println("Line: " + line);
}
System.out.println("Exception if any: " + in.ioException());
}
}
Aqui está um exemplo de uma invocação normal:
$ printf 'Hello\nWorld\n' > myfile && java Test myfile UTF-8
Line: Hello
Line: World
Exception if any: null
Aqui está o que você está vendo (exceto que você não recuperar e mostrar a exceção oculto). Aviso em particular que não há linhas são mostradas:
$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile UTF-8
Exception if any: java.nio.charset.MalformedInputException: Input length = 1
E aqui é quando decodificado como ISO-8859-1, a decodificação no qual todas as seqüências de bytes são válidos (embora 0x9C não atribuiu caráter e, portanto, não aparecer em um terminal):
$ printf 'Hello\nWorld \234\n' > myfile && java Test myfile ISO-8859-1
Line: Hello
Line: World
Exception if any: null
Se você está interessado apenas em dados ASCII e não tem nenhum UTF-8 cordas, você pode simplesmente pedir o scanner para uso ISO-8859-1
, passando-a como um segundo parâmetro para o Scanner
construtor:
Scanner in = new Scanner(new File(fileName), "ISO-8859-1");