Inserir dados em arquivos gigantes

10 respostas
Luiz_Augusto_Prado

Olá pessoal!

Qual a melhor forma de inserir ou excluir algum dado de um arquivo gigante utilizando “java.nio” ?

10 Respostas

nel

Luiz Augusto Prado:
Olá pessoal!

Qual a melhor forma de inserir ou excluir algum dado de um arquivo gigante utilizando “java.nio” ?

O que é um arquivo gigante ?

Luiz_Augusto_Prado

nel:
Luiz Augusto Prado:
Olá pessoal!

Qual a melhor forma de inserir ou excluir algum dado de um arquivo gigante utilizando “java.nio” ?

O que é um arquivo gigante ?

mais de 1 GB

Luiz_Augusto_Prado

Será que ninguem aqui no GUJ teve oportunidade de trabalhar desta forma ?

E

Não é o java.nio que resolve seu problema, e sim a estruturação adequada do seu arquivo gigante.

1GB não é tão gigante assim, e 100 KB é muito grande se você não souber estruturar os dados corretamente.

Para ter uma idéia, como é que o seu banco de dados preferido consegue inserir ou modificar rapidamente um registro em um arquivo de vários gigabytes de tamanho? Não é usando truques sujos de hardware :slight_smile:

Luiz_Augusto_Prado

entanglement:
Não é o java.nio que resolve seu problema, e sim a estruturação adequada do seu arquivo gigante.

1GB não é tão gigante assim, e 100 KB é muito grande se você não souber estruturar os dados corretamente.

Para ter uma idéia, como é que o seu banco de dados preferido consegue inserir ou modificar rapidamente um registro em um arquivo de vários gigabytes de tamanho? Não é usando truques sujos de hardware :slight_smile:

Extamente, de alguma forma o java deve oferecer algo semelhante.

Uma opção é criar um buffer e com este buffer em um canal ir buscando o dado que quero. Isso é fácil.
Mas o problema é como inserir algum dado logo após o dado encontrado.
Todo o conteúdo que vem a frente, de alguma forma deve ser empurrado para frente e só então, apos um flip, eu poderei escrever no buffer.

Pelo sei, com a biblioteca java.io as coisas ficam lentas. E como no banco de dados as coisas são bém rápidas.

Eu não preciso de um código pronto. Preciso de uma referência on-line ou de livro sobre isso. Até agora só encontrei sobre ler ou copiar para outro arquivo.
Por exemplo, copiaria tudo até onde quero inserir o novo dado em um arquivo temp, inseriria no temp o dado que quero, e só então daria continuidade na cópia do restante dos dados.

Eu imagino que alguem deve conhecer outra forma melhor.

Luiz_Augusto_Prado

Luiz Augusto Prado:
entanglement:
Não é o java.nio que resolve seu problema, e sim a estruturação adequada do seu arquivo gigante.

1GB não é tão gigante assim, e 100 KB é muito grande se você não souber estruturar os dados corretamente.

Para ter uma idéia, como é que o seu banco de dados preferido consegue inserir ou modificar rapidamente um registro em um arquivo de vários gigabytes de tamanho? Não é usando truques sujos de hardware :slight_smile:

Extamente, de alguma forma o java deve oferecer algo semelhante.

Uma opção é criar um buffer e com este buffer em um canal ir buscando o dado que quero. Isso é fácil.
Mas o problema é como inserir algum dado logo após o dado encontrado.
Todo o conteúdo que vem a frente, de alguma forma deve ser empurrado para frente e só então, apos um flip, eu poderei escrever no buffer.

Pelo sei, com a biblioteca java.io as coisas ficam lentas. E como no banco de dados as coisas são bém rápidas.

Eu não preciso de um código pronto. Preciso de uma referência on-line ou de livro sobre isso. Até agora só encontrei sobre ler ou copiar para outro arquivo.
Por exemplo, copiaria tudo até onde quero inserir o novo dado em um arquivo temp, inseriria no temp o dado que quero, e só então daria continuidade na cópia do restante dos dados.

Eu imagino que alguem deve conhecer outra forma melhor.

uma outra forma seria sempre ir inserindo os dados no final do arquivo na forma de lista encadeada. Ou seja desta forma teria que colocar na estrutura o apontador que vem antes e o apontador que vem depois, mudar os apontadores dos registro que vem antes e depois deste ultimo para apontarem para este ultimo registro. Só que estou achando isso uma volta muito grande para um arquivo de 1GB.

E

Você quer usar um truque como uma “Memory-mapped file”? Vou lhe dizer o que está errado nessa história.

Suponha que você tenha uma “memory-mapped file” de exatamente 1 GB e que você consiga mapear esse arquivo corretamente (pode ser que, por restrições de memória virtual, o que pode ocorrer em um sistema operacional de 32 bits, você não consiga mapear um arquivo desse tamanho, mas isso é história para depois).

Se você simplesmente fizer o equivalente a isto aqui: (supondo, é claro, que o arquivo mapeado em memória pudesse ser acessado como um array, o que é verdade em C mas não em Java, mas isso é outra história)

System.arraycopy (memoria, 0, memoria, 1024, tamanho da memoria - 1024);

ou seja, deslocar 1024 bytes para frente, o que irá ocorrer?

a) Se a alteração for efetivada (e esse tanto de memória for deslocada) então haverá a gravação de cerca de 1 Gb e a leitura de cerca de 1 Gb pelo sistema operacional, o que é obviamente algo que vai levar um certo tempo (digamos que você esteja usando um disco que consiga ler ou gravar 50 mb por segundo. Isso irá gastar cerca de 40 segundos, só para inserir um
b) Se a alteração não for efetivada, então só a memória será deslocada, o que irá levar o tempo referente ao deslocamento de 1 Gb dentro da memória (que por sinal não é tão insignificante assim; acho que é por volta de 100 ms, mas não fiz as contas adequadas).

Se for usado o esquema de arquivos de índices etc. que os bancos de dados usam, você não irá nem ler nem gravar tantos dados assim.

Arquivos mapeados em memória são úteis quando é necessário ter em arquivo dados em memória com layouts complexos e não muito grandes

E
Luiz_Augusto_Prado

entanglement:

Uma opção é criar um buffer e com este buffer em um canal ir buscando o dado que quero. Isso é fácil.
Mas o problema é como inserir algum dado logo após o dado encontrado.
Todo o conteúdo que vem a frente, de alguma forma deve ser empurrado para frente e só então, apos um flip, eu poderei escrever no buffer.

Você quer usar um truque como uma “Memory-mapped file”? Vou lhe dizer o que está errado nessa história.

Suponha que você tenha uma “memory-mapped file” de exatamente 1 GB e que você consiga mapear esse arquivo corretamente (pode ser que, por restrições de memória virtual, o que pode ocorrer em um sistema operacional de 32 bits, você não consiga mapear um arquivo desse tamanho, mas isso é história para depois).

Se você simplesmente fizer o equivalente a isto aqui: (supondo, é claro, que o arquivo mapeado em memória pudesse ser acessado como um array, o que é verdade em C mas não em Java, mas isso é outra história)

System.arraycopy (memoria, 0, memoria, 1024, tamanho da memoria - 1024);

ou seja, deslocar 1024 bytes para frente, o que irá ocorrer?

a) Se a alteração for efetivada (e esse tanto de memória for deslocada) então haverá a gravação de cerca de 1 Gb e a leitura de cerca de 1 Gb pelo sistema operacional, o que é obviamente algo que vai levar um certo tempo (digamos que você esteja usando um disco que consiga ler ou gravar 50 mb por segundo. Isso irá gastar cerca de 40 segundos, só para inserir um
b) Se a alteração não for efetivada, então só a memória será deslocada, o que irá levar o tempo referente ao deslocamento de 1 Gb dentro da memória (que por sinal não é tão insignificante assim; acho que é por volta de 100 ms, mas não fiz as contas adequadas).

Se for usado o esquema de arquivos de índices etc. que os bancos de dados usam, você não irá nem ler nem gravar tantos dados assim.

Arquivos mapeados em memória são úteis quando é necessário ter em arquivo dados em memória com layouts complexos e não muito grandes

Muito obrigado por sua explicação.
Estava imaginando que existia algum truque sujo de hardware por trás.
vc tem razão. Se eu fizer dessa forma vou realizar muitas gravações inúteis.

Estou tentando entender como os banco de dados funcionam porque eles me impressionam com a velocidade em que realizam o trabalho.
por exemplo uma busca em quem campo de nome na forma “%silva%” é diferente de uma busca na forma “silva”.

Quem criou estes bancos de dados são gênios.

Luiz_Augusto_Prado

Valeu!
A palavra chave que faltava para minha busca era arquivo de indice

fonte:
http://www.catalao.ufg.br/cc/marciodias/site_novo/wp-content/uploads/2009/08/Estrutura-de-Dados-2_Aula2.pdf

Existe uma flag para cada indice e que indica se o registro foi ou não excluido.  então, mais tarde, no momento da proxima reorganização que esse registro é excluido:


De tempos em tempos, é indicado que o arquivo seja reorganizado e re-indexado.
Nesta operação, todos os registros da Área de Extensão são copiados e inseridos fisicamente na ordem seqüencial correta, na Área de Dados, deixando então a Área de Extensão vazia (até que novas inclusões ocorram).

Criado 28 de junho de 2012
Ultima resposta 29 de jun. de 2012
Respostas 10
Participantes 3