Eu estou fazendo um toolkit para facilitar minha vida para leitura de arquivos/textos de diferentes tipos de codificação de forma automática, e usando as APIs do Java.
Em algum momento eu tenho que passar o conteúdo de um InputStreamReader para um CharBuffer… e o java faz isso pra mim: http://docs.oracle.com/javase/6/docs/api/java/io/Reader.html#read(java.nio.CharBuffer)
O meu código inicial era assim:
public void write (OutputStream output, int bufferSize) throws IOException{
Reader reader = getReader();
CharBuffer cbuff = CharBuffer.allocate(bufferSize);
ByteBuffer bbuff;
while(reader.read(cbuff) > 0){
bbuff = encoder.encode(cbuff);
output.write(bbuff.array());
cbuff.clear();
}
}
Eu percebi que o java.io.Reader.read(CharBuffer) acusava ter lido a quantidade correta de caracteres. Porém, o CharBuffer sempre ficava vazio, exceto na última iteração, quando termina o loop(e o buffer não foi preenchido até o final).
Enfim, no meu arquivo de teste, que converte uma codificação qualquer para utf-8, a única frase gravada no arquivo era um trecho final.
Mas o código parece certo, e vi que muita gente usa um código igual ao meu para copiar de um stream para um buffer.
Depois que eu percebi que o CharBuffer tem um método para encapsular um array, permitindo que eu altere diretamente os dados… resolvi tentar uma abordagem diferente…
public void write (OutputStream output, int bufferSize) throws IOException{
Reader reader = getReader();
char[] cbuffarr = new char[bufferSize];
CharBuffer cbuff = CharBuffer.wrap(cbuffarr);
ByteBuffer bbuff;
while(reader.read(cbuffarr) > 0){
bbuff = encoder.encode(cbuff);
output.write(bbuff.array());
cbuff.clear();
}
}
Dessa vez, chamando o método java.io.Reader.read(char[]) eu consegui os resultados esperados.
Eu gostaria de saber se alguém sabe o por que? Se eu estou fazendo algo errado? Ou provavelmente é bug do Java mesmo?
Eu achei que era a biblioteca do ICU4j que criava um InputStreamReader customizado onde a implementação podia ter uma falha, porém eu olhei o código… e eles usam o InputStreamReader do java mesmo