Performace na Leitura de muitos arquivos com Java

Bom o motivo deste post não é bem uma dúvida mais sim quero saber a opinião e conselhos de como proceder neste caso.
Caso:
Tenho uma aplicação Web onde neste aplicação tem uma Servlet que recebe das vários arquivos de várias estações de trabalho,
tais arquivos contém algumas informações importantes que precisa ser persistida no Banco de Dados.
Na minha aplicação Web eu recebo os arquivos e em um certo momento programado eu executo uma Thread que processa
os arquivos peneirando as informações que serão gravadas no Banco.
Como o número deste arquivos aumentou demais a minha Thread não ta dando conta do recado, esta demorando muito para
processar todos os arquivos, pois ao mesmo tempo que processa os arquivos, chega mais arquivos.
Bom eu gostaria de saber de sugestões de formas mais eficientes de ler um grande volume de arquivos.

Olá
Eu recomendo você usar as classes NIO
Comparação: http://geekomatic.ch/2008/09/06/1220730740479.html

furutani obrigado pela indicação!
Fiz um exemplo e vi em alguns post pela internet que ele realmente e mais eficiente.
Neste exemplo:

FileInputStream stream = new FileInputStream(job);
FileChannel channel = stream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
			
    String text = "";
    while(channel.read(buffer) != -1){
	buffer.flip();
	CharBuffer charBuffer = Charset.forName("UTF-8").decode(buffer);
	text = charBuffer.toString();
	buffer.clear();
     }
     System.out.println("|> "+ text)

Dessa forma o While só é executado uma vez ou seja ele recupera o texto todo.
Teria alguma maneira de pegar linha por linha do meu arquivo?

[quote=jweibe]Bom o motivo deste post não é bem uma dúvida mais sim quero saber a opinião e conselhos de como proceder neste caso.
Caso:
Tenho uma aplicação Web onde neste aplicação tem uma Servlet que recebe das vários arquivos de várias estações de trabalho,
tais arquivos contém algumas informações importantes que precisa ser persistida no Banco de Dados.
Na minha aplicação Web eu recebo os arquivos e em um certo momento programado eu executo uma Thread que processa
os arquivos peneirando as informações que serão gravadas no Banco.
Como o número deste arquivos aumentou demais a minha Thread não ta dando conta do recado, esta demorando muito para
processar todos os arquivos, pois ao mesmo tempo que processa os arquivos, chega mais arquivos.
Bom eu gostaria de saber de sugestões de formas mais eficientes de ler um grande volume de arquivos.
[/quote]

  1. Qual a quantidade desses arquivos no diretório em que eles estão?
  2. O tamanho desses arquivos, individualmente, é superior a 8MB?
  3. Qual e o filesystem em que esses arquivos estão? (Um exemplo de resposta: NTFS em Windows Server 2008)

[quote=jweibe]furutani obrigado pela indicação!
Fiz um exemplo e vi em alguns post pela internet que ele realmente e mais eficiente.
Neste exemplo:

FileInputStream stream = new FileInputStream(job);
FileChannel channel = stream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate((int) channel.size());
			
    String text = "";
    while(channel.read(buffer) != -1){
	buffer.flip();
	CharBuffer charBuffer = Charset.forName("UTF-8").decode(buffer);
	text = charBuffer.toString();
	buffer.clear();
     }
     System.out.println("|> "+ text)

Dessa forma o While só é executado uma vez ou seja ele recupera o texto todo.
Teria alguma maneira de pegar linha por linha do meu arquivo?[/quote]

public void lerArquivo(File arquivoLeitura) {
long tamanhoArquivo = arquivoLeitura.length();
				FileInputStream fs = new FileInputStream(arquivoLeitura);
				DataInputStream in = new DataInputStream(fs);
				LineNumberReader lineRead = new LineNumberReader(
						new InputStreamReader(in));
				String line = null;
				int count = 0;
				while ((line = lineRead.readLine()) != null) {
                                    print(line);

}



[quote=entanglement]

  1. Qual a quantidade desses arquivos no diretório em que eles estão?

  2. O tamanho desses arquivos, individualmente, é superior a 8MB?

  3. Qual e o filesystem em que esses arquivos estão? (Um exemplo de resposta: NTFS em Windows Server 2008)[/quote]

  4. O diretorio possui mais ou menos uns 27GB de arquivos.

  5. O tamanho de cada arquivo e bem irrelevante pois todos são pequenos, podendo variar de 27Kb a 1.5Mb.

  6. O Servidor e um Windows Server 2008 (NTFS).

27 GB de arquivos são quantos arquivos que estão nesse diretório? Ou é uma coleção de subdiretórios, cada um tendo menos de 1000 arquivos?

Como você disse que os arquivos são bem pequenos, estou vendo que o seu grande problema não é o tempo de processar o arquivo (1 MB é um arquivo que pode ser lido de uma vez só usando um BufferedReader com o valor do buffer ajustado para 1 MB), mas o tempo para abri-lo.

Eu tinha um colega que teve exatamente a mesma idéia que você (usar java.nio) mas ele, depois de muito esforço, descobriu que não valeu a pena.

Faça um pequeno teste. Crie um programa que simplesmente abra, para leitura, e feche cada um dos arquivos que estão nesse diretório, sem ler absolutamente nada dele. Meça quanto tempo levou esse processo. A seguir, rode o mesmo programa em um diretório que tenha menos arquivos. Você vai ver que o tempo que leva para abrir um arquivo em um diretório que tem muitos arquivos é bem maior que o tempo que leva para abrir um arquivo em um diretório que tem menos arquivos.

[quote=entanglement]27 GB de arquivos são quantos arquivos que estão nesse diretório? Ou é uma coleção de subdiretórios, cada um tendo menos de 1000 arquivos?

Como você disse que os arquivos são bem pequenos, estou vendo que o seu grande problema não é o tempo de processar o arquivo (1 MB é um arquivo que pode ser lido de uma vez só usando um BufferedReader com o valor do buffer ajustado para 1 MB), mas o tempo para abri-lo.

Eu tinha um colega que teve exatamente a mesma idéia que você (usar java.nio) mas ele, depois de muito esforço, descobriu que não valeu a pena.

[/quote]

entanglement é apenas um diretório só contendo todos os arquivos…
Pelos teste que eu realizei eu percebi que o tempo que leva pra ler os arquivos usando java.io ou java.nio e muito irrisório tendo em vista que os arquivos
são todos pequenos(porém em arquivos grandes a diferença e bem grande, mais não e o meu caso).
O problema maior que eu to tendo e como processar esse grande volume de arquivos.
Eu to até cogitando a possibilidade de fazer uma implementação em C++ pra leitura deste arquivos pra ver se melhora a performance.

Uma forma de resolver isso é o seguinte: digamos que seus arquivos sejam numerados como:

0000001.bin
0000002.bin

1234123.bin

9929928.bin

ou coisa parecida. Como você deve ter percebido, há uns 30 ou 40 mil arquivos em um unico diretório.

Se puder criar uma estrutura de subdiretórios e repartir seus arquivos, mais ou menos como:

0000\001.bin
0000\002.bin

1234\123.bin

9929\928.bin

(cada diretório vai ter no máximo 1000 arquivos nesse caso),

então você provavelmente irá melhorar bem o desempenho na hora de abrir os arquivos.

O Java7 teve a classe File melhorada - http://docs.oracle.com/javase/tutorial/essential/io/fileio.html
Talvez te ajude.

[quote=jaboot]O Java7 teve a classe File melhorada - http://docs.oracle.com/javase/tutorial/essential/io/fileio.html
Talvez te ajude. [/quote]

Não posso usar Java 7… somente o 6

[quote=entanglement]Uma forma de resolver isso é o seguinte: digamos que seus arquivos sejam numerados como:

0000001.bin
0000002.bin

1234123.bin

9929928.bin

ou coisa parecida. Como você deve ter percebido, há uns 30 ou 40 mil arquivos em um unico diretório.

Se puder criar uma estrutura de subdiretórios e repartir seus arquivos, mais ou menos como:

0000\001.bin
0000\002.bin

1234\123.bin

9929\928.bin

(cada diretório vai ter no máximo 1000 arquivos nesse caso),

então você provavelmente irá melhorar bem o desempenho na hora de abrir os arquivos.

[/quote]

entanglement é uma solução, vou fazer testes em cima do que você me falou.
Mais quanto e fazer um aplicativo para ler estes arquivos em C++, será se melhora a performance de leitura?

Boa pergunta. O tempo de abrir um arquivo é dado pelo sistema operacional, não pelo Java ou C++. Pelo que acredito (mas obviamente não tenho como testar), o tempo que domina é o tempo de abrir o arquivo, não o de processá-lo.