Ler grupo de caracteres de arquivo > 30GB - tem como sem saber o tamanho total? [RESOLVIDO]

Pessoal. Estou lendo um arquivo um tanto grande (> 30GB), que só possui uma linha. Precisava dividir o texto desse arquivo em arquivos menores de 6 dígitos cada.

Não posso ler linha a linha, pois só tem 1, e o Java não ia gostar nada de guardar 30GB de informação em uma única string. :smiley:

Também não posso ler o arquivo usando como referência seu tamanho (ex: continuar enquanto tamanho for maior que 0), pois acredito que nem eu um BigInteger cabe a quantidade de caracteres que possui um arquivo de 30GB.

Eu estava lendo caractere por caractere, só parando a leitura quando o caractere fosse null, mas como podem ver, isso não é a melhor maneira de se fazer isso.

Queria ler um grupo x (no caso: 6) de caracteres por vez (se possível), mas não posso me basear no tamanho do arquivo ou quanto falta para acabar. Tentei umas gambiarras do tipo: continuar enquanto o valor lido for diferente de null, mas não ta dando.

Preciso de ajuda, to bem perdido nisso. Se alguém tiver um código que me ajude, vai se muito bem vindo.

Muito obrigado

Pelo que eu entendi, vc quer ler o arquivo de 6 em 6 bytes…
Fiz um pequeno código lendo de 6 em 6 bytes.

Na parte onde está System.out.println(Arrays.toString(bytes)); vc pode substituir pelo código que irá gravar em um novo arquivo.

[code] public static void main(String[] args) throws FileNotFoundException, IOException {
FileInputStream f = null;
try {
f = new FileInputStream(“c:\seuArquivo.txt”);
byte[] bytes = new byte[6];

        while (f.read(bytes, 0, 6) != -1) {
            System.out.println(Arrays.toString(bytes));
        }

    } finally {
        if (f != null) {
            f.close();
        }
    }
}[/code]

espero ter ajudado

[quote=eliangela]Pelo que eu entendi, vc quer ler o arquivo de 6 em 6 bytes…
Fiz um pequeno código lendo de 6 em 6 bytes.

Na parte onde está System.out.println(Arrays.toString(bytes)); vc pode substituir pelo código que irá gravar em um novo arquivo.

[code] public static void main(String[] args) throws FileNotFoundException, IOException {
FileInputStream f = null;
try {
f = new FileInputStream(“c:\seuArquivo.txt”);
byte[] bytes = new byte[6];

        while (f.read(bytes, 0, 6) != -1) {
            System.out.println(Arrays.toString(bytes));
        }

    } finally {
        if (f != null) {
            f.close();
        }
    }
}[/code]

espero ter ajudado[/quote]

Ok, vlw pela ajuda, vou testar.

vlw

Arrays é uma classe, toString é um método que converte o parâmetro passado em uma string.

)’] documentação

[quote=maior_abandonado]Arrays é uma classe, toString é um método que converte o parâmetro passado em uma string.

)"] documentação [/quote]

Mal aew, coloquei lá no Eclipse daí eu fui ver. :roll:

Kra, testei e ficou perfeito, tu caiu do céu. :smiley:

Vlw msm, abrass.

Leia este programa e veja por que é que você nunca deve ler 1 byte de cada vez, nem é preciso saber o tamanho do arquivo anteriormente.

import java.util.*;
import java.io.*;

class Quebra {
    public Quebra (final File inputFile_, final int chunkSize_) {
        inputFile = inputFile_; chunkSize = chunkSize_;
    }
    private File inputFile; private int chunkSize;
    public void quebrar () {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        File outputFile;
        int currentFileNumber = 0;
        try {
            fis = new FileInputStream (inputFile);
            byte[] buffer = new byte [chunkSize]; // nada de arquivos excessivamente grandes - se o arquivo for
            // muito grande, sinto muito, iremos cair por "OutOfMemoryException". Uma simplificação, poderíamos
            // usar um buffer bem menor, só tomando cuidado com os tamanhos certos dos arquivos.
            int bytesLidos;
	    while ((bytesLidos = fis.read (buffer)) > 0) {
                outputFile = new File (inputFile.getPath() + String.format (".%03d", currentFileNumber));
                fos = new FileOutputStream (outputFile);
                fos.write (buffer, 0, bytesLidos);
                fos.close(); fos = null;
                currentFileNumber++;
            }            
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try { if (fis != null) fis.close(); } catch (IOException ex) { }
            try { if (fos != null) fos.close(); } catch (IOException ex) { }
        }
    }
    public static void main (String[] args) {
        if (args.length != 2) {
            System.err.println ("Sintaxe: java -cp . Quebra arquivo tamanho");
            System.err.println ("Exemplo: java -cp . Quebra arquivogrande.txt 1000000");
            System.err.println ("   quebra o arquivogrande.txt em vários arquivos de 1000000 bytes, com o nome ");
            System.err.println ("   arquivogrande.txt.000, arquivogrande.txt.001 etc.");
            System.exit (1);
        }
        Quebra q = new Quebra (new File (args[0]), Integer.parseInt (args[1]));
        q.quebrar();
    }
}