[Resolvido] Como ler um arquivo texto com 56847 linhas em um app Android

5 respostas
J

Tenho um processo que faz download de arquivos textos onde cada linha será convertida para um tipo de objeto e inserida no banco (eu uso o Hadi).

Tenho um arquivo de clientes que tem 56.847 linhas e está dando erro de memória quando tento ler linha a linha usando o Scanner.
Erro:

05-07 10:30:23.890: E/AndroidRuntime(23724): FATAL EXCEPTION: AsyncTask #1 05-07 10:30:23.890: E/AndroidRuntime(23724): Process: br.com.csagestoes.gestor, PID: 23724 05-07 10:30:23.890: E/AndroidRuntime(23724): java.lang.RuntimeException: An error occured while executing doInBackground() 05-07 10:30:23.890: E/AndroidRuntime(23724): at android.os.AsyncTask$3.done(AsyncTask.java:300) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.FutureTask.setException(FutureTask.java:222) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.FutureTask.run(FutureTask.java:242) 05-07 10:30:23.890: E/AndroidRuntime(23724): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.lang.Thread.run(Thread.java:841) 05-07 10:30:23.890: E/AndroidRuntime(23724): Caused by: java.lang.OutOfMemoryError 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.lang.String.<init>(String.java:422) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.lang.String.copyValueOf(String.java:721) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.nio.CharArrayBuffer.toString(CharArrayBuffer.java:168) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.regex.Matcher.reset(Matcher.java:205) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.regex.Matcher.reset(Matcher.java:177) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.Scanner.resetMatcher(Scanner.java:1671) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.Scanner.findWithinHorizon(Scanner.java:476) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.Scanner.hasNextLine(Scanner.java:794) 05-07 10:30:23.890: E/AndroidRuntime(23724): at br.com.csagestoes.gestor.util.FtpServerUtil.downloadAndRead(FtpServerUtil.java:165) 05-07 10:30:23.890: E/AndroidRuntime(23724): at br.com.csagestoes.gestor.HomeActivity$FtpTask.doInBackground(HomeActivity.java:160) 05-07 10:30:23.890: E/AndroidRuntime(23724): at br.com.csagestoes.gestor.HomeActivity$FtpTask.doInBackground(HomeActivity.java:1) 05-07 10:30:23.890: E/AndroidRuntime(23724): at android.os.AsyncTask$2.call(AsyncTask.java:288) 05-07 10:30:23.890: E/AndroidRuntime(23724): at java.util.concurrent.FutureTask.run(FutureTask.java:237) 05-07 10:30:23.890: E/AndroidRuntime(23724): ... 4 more

Alguém sabe de alguma forma alternativa para eu ler esse arquivo linha a linha? E mais, conforme vou lendo a linha preciso adicionar numa List e enviar essa lista para um outro método que faz um parse e insere no banco de dados.

Código:

... boolean fileCreated = tempFile.exists(); if (fileCreated) { Scanner fileScanner = new Scanner(tempFile);//new Scanner(new InputStreamReader(stream)); while (fileScanner.hasNextLine()) { // erro aqui: linha 165 String rowContent = fileScanner.nextLine(); rows.add(rowContent); } fileScanner.close(); } tempFile.delete(); ...

5 Respostas

A

Divide o tratamento do arquivo, se cada linha vai gerar um registro no db, trata em lotes, por exemplo de 1000 em 1000. Procure por produtor/consumidor.

J

Mas o problema dá quando eu tento adicionar a linha lida numa List ou HashSet, e também eu não sei quantas linhas o arquivo vai ter antes de percorrer ele todo.

Teria algum exemplo disso que você indicou?

A

javer:
Mas o problema dá quando eu tento adicionar a linha lida numa List ou HashSet, e também eu não sei quantas linhas o arquivo vai ter antes de percorrer ele todo.

Teria algum exemplo disso que você indicou?


Justamente por isso, você está lendo todo o arquivo e colocando na memória. Multiplique o tamanho de uma linha pelo número de linhas e vai ver quando de memória vai ocupar. Por isso mesmo, a cada lote completado na leitura começa a gravar no banco, não vai ter que guardar tudo na memória.

J

Seria,

Tamanho da linha: 72 caracteres
Quantidade de linhas: 56.847
Total: 4.092.984,00

J

Resolvido,

Eu simplesmente não coloco nada em Lista nenhuma, vou lendo a linha fazendo parte e já inserindo no banco.

Criado 7 de maio de 2015
Ultima resposta 11 de mai. de 2015
Respostas 5
Participantes 2