2015-08-20 19 views
8

Ho un grande file .csv (circa 300 MB), che viene letto da un host remoto e analizzato in un file di destinazione, ma non è necessario copiare tutte le righe nel file di destinazione. Durante la copia, ho bisogno di leggere ogni riga dall'origine e se passa qualche predicato, aggiungi la linea al file di destinazione.Come posso elaborare un file di grandi dimensioni tramite CSVParser?

Suppongo che Apache CSV (apache.commons.csv) può analizzare solo file intero

CSVFormat csvFileFormat = CSVFormat.EXCEL.withHeader(); 
CSVParser csvFileParser = new CSVParser("filePath", csvFileFormat); 
List<CSVRecord> csvRecords = csvFileParser.getRecords(); 

quindi non posso usare BufferedReader. In base al mio codice, è necessario creare un'istanza new CSVParser() per ogni riga, che appare inefficiente.

Come è possibile analizzare una singola riga (con l'intestazione nota della tabella) nel caso sopra?

risposta

10

Indipendentemente da ciò che si fa, tutti i dati del file verranno trasferiti sul computer locale perché il sistema deve analizzarli per determinarne la validità. Sia che il file arrivi tramite un file letto attraverso il parser (in modo da poter analizzare ogni riga), sia che copi solo l'intero file per scopi di analisi, verrà tutto in locale. Avrai bisogno di ottenere i dati locali, quindi tagliare l'eccesso.

Chiamare csvFileParser.getRecords() è già una battaglia persa perché the documentation spiega che tale metodo carica ogni riga del file in memoria. Per analizzare il record conservando la memoria attiva, dovresti invece scorrere su ogni record; la documentazione comporta i seguenti carichi di codice un record di memoria alla volta:

CSVParser csvFileParser = CSVParser.parse(new File("filePath"), csvFileFormat); 

for (CSVRecord csvRecord : csvFileParser) { 
    ... // qualify the csvRecord; output qualified row to new file and flush as needed. 
} 

Dal momento che lei ha spiegato che "filePath" non è locale, la soluzione di cui sopra è incline al fallimento a causa di problemi di connettività. Per eliminare i problemi di connettività, ti consiglio di copiare l'intero file remoto su locale, assicurarti che il file venga copiato accuratamente confrontando i checksum, analizzando la copia locale per creare il file di destinazione, quindi elimina la copia locale dopo il completamento.

0

Questa è una risposta in ritardo, ma è possibile utilizzare un BufferedReader con la CSVParser:

try (BufferedReader reader = new BufferedReader(new FileReader(fileName), 1048576 * 10)) { 
    Iterable<CSVRecord> records = CSVFormat.RFC4180.parse(reader); 
    for (CSVRecord line: records) { 
     // Process each line here 
    } 
catch (...) { // handle exceptions from your bufferedreader here 
Problemi correlati