Estou lendo um campo de uma base de dados via conexão ODBC.
Este campo que estou lendo armazena textos bem grandes(sei disso devido a um software que usamos que exibe estes dados, não tenho acesso ao banco, nem mesmo sei que tipo de banco é
)
InputStream is = rs.getAsciiStream(("Detailed_Description"));
try {
int data = is.read();
while(data != -1){
System.out.print((char)data);
data = is.read();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Ocorre que ao ler um campo que tenha algum texto ele imprime até o último caracter normalmente e depois do último ele trava nesta linha data = is.read() .
O código simplesmente trava.
Fiz o debug no eclipse para ver o que acontece e não consegui identificar nada de estranho, apenas reparei uma coisa na variável do input stream. Até onde sei quando terminam os bytes e utilizamos o método InputStream.read() ele retorna o valor -1, olhando o buffer desta variável depois de preenchida, depois que terminam os bytes, em nenhum momento visualizo o -1 indicando o término, apenas vários chars com 0.
A propósito, não aconselho ler um caracter de cada vez de um InputStream - é uma operação assustadoramente lenta.
Se o InputStream é um arquivo-texto, você pode simplesmente encapsular esse InputStream com um InputStreamReader e um BufferedReader, e ler os dados linha por linha com readLine(). Quando readLine() retorna null, o texto acabou.
Obrigado pela sugestão entanglement, na realidade eu uso o BufferedReader, apenas retirei neste caso para simplificar meu código a fim de focar extamente no problema. Com o BufferedReader acontece a mesma coisa, o código trava na leitura da linha.
Hum… será que você vai ter de fazer uma gambiarra do tipo “fazer o read cair por InterruptedException se ele demorar muito”?
EDIT - agora que vi que é ODBC. Se fizer o read cair por InterruptedException é bem capaz de a conexão acabar ficando instável desse ponto para frente ![:frowning: :frowning:](https://www.guj.com.br/images/emoji/twitter/frowning.png?v=9)
Realmente, não gosto muito do ODBC quando acessado via JDBC. Talvez haja algum bug nesse driver ODBC que só se manifesta quando é acessado via JDBC.
Existe alguma forma de acessar esse banco usando um driver JDBC específico para esse banco, em vez de usar o ODBC?
Estou conectando na base de dados de um software chamado BMC Remedy ARS. Até tem um driver JDBC disponibilizado pela comunidade, mas não tem suporte e é cheio de bugs(https://communities.bmc.com/docs/DOC-22516).
Existe uma aplicação feiosa hoje aqui na empresa feita em banco de dados access com formulários que consegue ler este e outros campos normalmente.
No access ele entende este tipo de campo como sendo um memorando.
Estou refazendo esta aplicação em java.
Será que não vai ter jeito ? ![:frowning: :frowning:](https://www.guj.com.br/images/emoji/twitter/frowning.png?v=9)
Descobri mais algumas informações que podem ajudar no problema.
Usando o método getColumnTypeName do objeto ResultSetMetaData consegui descobrir que o tipo SQL desta coluna é LONGVARCHAR.
E infelizmente parece que este tipo apresenta alguns problemas nativamente com o java pelo que está descrito em http://docs.oracle.com/javase/1.5.0/docs/guide/jdbc/getstart/mapping.html#1055141.
O tutorial desta página recomenda a utilização do método getAsciiStream(), utilizando ele retorna um input stream, mas ao tentar ler os dados ocorre o travamento ao chegar depois do último caracter como tinha dito.
Existe alguma forma de trabalhar corretamente com o tipo SQL LONGVARCHAR ? Usando alguma biblioteca ou coisa do tipo ?
EDIT -
Encontrei exatamente o mesmo problema que tenho em uma questão no Stack Overflow http://stackoverflow.com/questions/14344683/getting-value-fom-a-resultset-hangs. Infelizmente não tiveram resposta.
Somente para informar que consegui resolver o problema. Usando o driver específico da aplicação. Postei a dúvida no forum da aplicação e solucionaram o problema.
https://communities.bmc.com/thread/91582
Realmente só foi possível o correto funcionamento via um driver nativo.