2010-12-17 9 views
5

Scenario:sta lanciando un'operazione costosa?

  • Sto analisi di un (file carattere) file di grandi dimensioni. Ad esempio un file .csv (non esattamente il mio caso)
  • Non riesco a tenere l'intero file in memoria. Quindi devo attuare una strategia tampone.
  • Voglio costruire un gestore generico che manterrà un numero costante di righe in memoria (come stringhe). Questo gestore recupera altre linee se necessario rimuovendo le linee non necessarie.
  • Su questo gestore creerò un parser che trasformerà le linee in oggetti Java e opererà modifiche su quegli oggetti. Una volta apportate le modifiche (aggiorna alcuni campi sugli oggetti), le modifiche rimandano al file.

Devo:

  • Invece di mantenere il buffer come un array di stringhe, devo mantenere il buffer direttamente come oggetti (facendo un unico getto)? oppure ...
  • Conservare il buffer come linee, ogni volta che devo operare sul buffer, inoltrare le informazioni all'oggetto giusto, apportare le modifiche, mantenere le modifiche sul file. Le operazioni sequenziali necessitano di cast supplementari.

Dovrò mantenere le cose semplici. Qualche suggerimento?

+1

In che modo si fondono le stringhe su altri tipi di dati? –

+1

stai parlando di casting o parsing? – fortran

+0

È più complicato. Non è esattamente un cast da/a String, c'è un'interfaccia Row e più implementazioni. Ogni implementazione è come un contenitore, che restituisce un oggetto. Quell'oggetto deve essere lanciato. Se devo fare alcune modifiche su una riga specifica, sono necessari alcuni calchi nel meccanismo interno. –

risposta

8

La trasmissione non modifica la quantità di memoria occupata da un oggetto. Cambia solo il tipo di runtime.

Se è possibile eseguire tali operazioni su una base per riga, eseguire l'operazione immediatamente all'interno del ciclo in cui si legge una singola riga.

while ((line = reader.readLine()) != null) { 
    line = process(line); 
    writer.println(line); 
} 

In questo modo si finisce sempre con una sola riga nella memoria Java ogni volta anziché l'intero file.

Oppure, se avete bisogno di fare quelle operazioni in base al file tutto il CSV (vale a dire, quelle operazioni dipendono tutti le righe), allora la cosa più efficace è quello di importare il file CSV in un database SQL reale e poi utilizzare le istruzioni SQL per modificare i dati e quindi esportarli nuovamente in file CSV.

3

Si consiglia di utilizzare un MappedByteBuffer (di NIO), che è possibile utilizzare per leggere un file troppo grande per adattarsi alla memoria. Mappa solo una regione del file in memoria; una volta che hai finito di leggere questa regione (ad esempio, la prima 10k), mappare la prossima e così via, fino a quando non hai letto l'intero file. Memoria efficiente e abbastanza facile da implementare.

2

Java Calchi: come

Object a = new String(); 
String b (String) a; 

non sono costosi. - Non importa se lanci Stringhe o qualsiasi altro tipo.

1

Il tuo valore reale add sarà quello di leggere ogni riga come una stringa, che è piuttosto facile in Java.Dopo è in una stringa, è banale per dividere la stringa su ogni virgola con

String[] row = parsedRow.split(",");

L'avrete una stringa per ogni valore nella matrice, che possono poi essere operato.

+0

Considera cosa farà la tua chiamata 'split()' a '123," abc, def ", ghi'. –

+0

@JUST IL MIO OPINIONE corretto - debitamente annotato, ma poi stai iniziando a entrare in un caso marginale dato il mio esempio semplicistico che presuppone che una virgola sarà sempre un separatore e mai contenuta all'interno di una stringa. – bakoyaro

Problemi correlati