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

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(); ...

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.

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?

[quote=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?[/quote]
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.

Seria,

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

Resolvido,

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