Ler arquivo de trás para frente  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

Buenas,
Tô utilizando BufferedReader para ler o conteúdo de um arquivo, porém pelo que sempre usei ele só lê sequencialmente, e nãoe xiste nenhum método com informações sobre o arquivo(qtde linhas, carateres, etc).
E eu tô precisando ler por exemplo os 50 últimos registros de um arquivo, alguém tem uma idéia de como fazer isso, tô quebrando a cabeça aqui e num vejo como.

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Uma forma boboca é ler o arquivo do início para o fim mesmo, mas deixando as linhas em um LinkedList cujo comprimento você limita a 50 linhas.
Como é que você faz isso? Algo como:
[WWW]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

Hun, xeu testar essa solução.
A zica é que é pra gerar aquele arquivo da Receita Federal - IN86-, e a ordem anual de um arquivo desse é de alguns milhões de linha. De qualquer forma, grato pela sugestão.

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
#@®®¡$
Moderador
[Avatar]

Membro desde: 13/02/2004 09:42:28
Mensagens: 807
Localização: São Paulo
Offline

Ixe. Se a quantidade de bytes do que você quer ler for fixa, você pode usar o File.length para ver o tamanho do arquivo e indicar quantos bytes você quer ler usando http://java.sun.com/j2se/1.5.0/docs/api/java/io/FileInputStream.html#read(byte[],%20int,%20int) <-- Copie a URL

Se não houver problema em ler todo o arquivo, você pode usar Commons IO, que tem CountingInputStream e FileUtils.readLines().

Wilerson "#@®®¡$" de Oliveira
http://mundoestranho.net/blog/
Douglas Adams wrote:I love deadlines. I like the whooshing sound they make as they fly by.
[WWW] [ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

Num é fixo não, é retorno de um SELECT que monta o arquivo.

Thingol, creio que me perdi ali no seu algoritmo, depois da posição máxima ele não vai retirar e inserir sempre na primeira posição?

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Já que o arquivo tem alguns milhões de linhas, você pode usar o método usado pelo "tail". O "tail" (utilitário do Unix) pega o arquivo e o lê usando o análogo ao RandomAccessFile (o programa é em C), pegando os últimos KBytes e procurando os caracteres usados para quebra de linha, para formar as linhas.

Você pode usar o próprio "tail", se estiver no Unix. É mais rápido que escrever o seu.
[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Rafael Nunes wrote:Num é fixo não, é retorno de um SELECT que monta o arquivo.

Thingol, creio que me perdi ali no seu algoritmo, depois da posição máxima ele não vai retirar e inserir sempre na primeira posição?


add sempre insere na última, e remove(0) sempre deleta da primeira. Essa é a idéia.


[WWW]
#@®®¡$
Moderador
[Avatar]

Membro desde: 13/02/2004 09:42:28
Mensagens: 807
Localização: São Paulo
Offline

Rafael Nunes wrote:Num é fixo não, é retorno de um SELECT que monta o arquivo.


Não rola de fazer um COUNT e um LIMIT nessa query?

Wilerson "#@®®¡$" de Oliveira
http://mundoestranho.net/blog/
Douglas Adams wrote:I love deadlines. I like the whooshing sound they make as they fly by.
[WWW] [ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

thingol wrote:Já que o arquivo tem alguns milhões de linhas, você pode usar o método usado pelo "tail". O "tail" (utilitário do Unix) pega o arquivo e o lê usando o análogo ao RandomAccessFile (o programa é em C), pegando os últimos KBytes e procurando os caracteres usados para quebra de linha, para formar as linhas.


Como isso vai ser um job que vai rodar de madrugada, vou deixar a sua primeira solução mesmo, só rezar pra num dar OutOfMemory no servidor de madrugada...hehe
Bregadão.

Quanto ao Count/Limit, se tiver algum problema com essa sugestão do thingol, vou acabar lendo essas linhas direto do select mesmo.
[Email]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Um problema na minha solução é que size(), para LinkedList, envolve percorrer a lista inteira. Se eu usasse um ArrayList a parte de inserção e remoção de elementos é mais lenta, mas em compensação o cálculo de tamanho é mais rápido. Não sei se faz alguma diferença.
[WWW]
peczenyj
Moderador
[Avatar]

Membro desde: 26/03/2006 23:25:37
Mensagens: 3191
Localização: Rio de Janeiro
Offline

inverte a ordem com um ORDER BY ... DESC

http://pacman.blog.br

'Não importa quanto alguém se dedique à tarefa. Ninguém consegue fazer a água da cascata cair para cima.'
[WWW]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

thingol wrote:Um problema na minha solução é que size(), para LinkedList, envolve percorrer a lista inteira. Se eu usasse um ArrayList a parte de inserção e remoção de elementos é mais lenta, mas em compensação o cálculo de tamanho é mais rápido. Não sei se faz alguma diferença.


Mas como a lista sempre vai ser pequena(30/50) elementos, num vejo muita perda de performance nisso.
[Email]
#@®®¡$
Moderador
[Avatar]

Membro desde: 13/02/2004 09:42:28
Mensagens: 807
Localização: São Paulo
Offline

Rafael Nunes wrote:
thingol wrote:Um problema na minha solução é que size(), para LinkedList, envolve percorrer a lista inteira. Se eu usasse um ArrayList a parte de inserção e remoção de elementos é mais lenta, mas em compensação o cálculo de tamanho é mais rápido. Não sei se faz alguma diferença.


Mas como a lista sempre vai ser pequena(30/50) elementos, num vejo muita perda de performance nisso.


Você mesmo disse que seu arquivo tem zilhões de linhas. Depois que ele ler a 50ª, vai percorrer a lista inteira (tá, são só 50 elementos, mas vai percorrer) zilhões - 50 vezes.

É melhor manter um contadorzinho manual.
[WWW] [ICQ]
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team