Univocity Parsers

1. Introduzione

In questo tutorial, daremo una rapida occhiata a Univocity Parsers, una libreria per l'analisi di file CSV, TSV e a larghezza fissa in Java.

Inizieremo con le basi della lettura e scrittura di file prima di passare alla lettura e alla scrittura di file da e verso Java Bean. Quindi, daremo una rapida occhiata alle opzioni di configurazione prima di concludere.

2. Configurazione

Per utilizzare i parser, dobbiamo aggiungere l'ultima dipendenza Maven al nostro file pom.xml del progetto :

 com.univocity univocity-parsers 2.8.4 

3. Utilizzo di base

3.1. Lettura

In Univocity, possiamo analizzare rapidamente un intero file in una raccolta di array di stringhe che rappresentano ogni riga del file.

Innanzitutto, analizziamo un file CSV fornendo un lettore al nostro file CSV in un CsvParser con le impostazioni predefinite:

try (Reader inputReader = new InputStreamReader(new FileInputStream( new File("src/test/resources/productList.csv")), "UTF-8")) { CsvParser parser = new CsvParser(new CsvParserSettings()); List parsedRows = parser.parseAll(inputReader); return parsedRows; } catch (IOException e) { // handle exception }

Possiamo facilmente cambiare questa logica per analizzare un file TSV passando a TsvParser e fornendogli un file TSV.

È solo leggermente più complicato elaborare un file a larghezza fissa. La differenza principale è che dobbiamo fornire le nostre larghezze di campo nelle impostazioni del parser.

Leggiamo un file a larghezza fissa fornendo un oggetto FixedWidthFields al nostro FixedWidthParserSettings :

try (Reader inputReader = new InputStreamReader(new FileInputStream( new File("src/test/resources/productList.txt")), "UTF-8")) { FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10); FixedWidthParserSettings settings = new FixedWidthParserSettings(fieldLengths); FixedWidthParser parser = new FixedWidthParser(settings); List parsedRows = parser.parseAll(inputReader); return parsedRows; } catch (IOException e) { // handle exception }

3.2. Scrittura

Ora che abbiamo trattato la lettura dei file con i parser, impariamo come scriverli.

Scrivere file è molto simile alla loro lettura in quanto forniamo un writer insieme alle impostazioni desiderate al parser che corrisponde al nostro tipo di file.

Creiamo un metodo per scrivere file in tutti e tre i formati possibili:

public boolean writeData(List products, OutputType outputType, String outputPath) { try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)),"UTF-8")){ switch(outputType) { case CSV: CsvWriter writer = new CsvWriter(outputWriter, new CsvWriterSettings()); writer.writeRowsAndClose(products); break; case TSV: TsvWriter writer = new TsvWriter(outputWriter, new TsvWriterSettings()); writer.writeRowsAndClose(products); break; case FIXED_WIDTH: FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10); FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths); FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings); writer.writeRowsAndClose(products); break; default: logger.warn("Invalid OutputType: " + outputType); return false; } return true; } catch (IOException e) { // handle exception } }

Come per la lettura dei file, la scrittura di file CSV e file TSV è quasi identica. Per i file a larghezza fissa, dobbiamo fornire la larghezza del campo alle nostre impostazioni.

3.3. Utilizzo di processori di riga

Univocity fornisce una serie di processori di riga che possiamo utilizzare e ci offre anche la possibilità di crearne uno nostro.

Per avere un'idea dell'utilizzo dei processori di riga, utilizziamo BatchedColumnProcessor per elaborare un file CSV più grande in batch di cinque righe:

try (Reader inputReader = new InputStreamReader(new FileInputStream(new File(relativePath)), "UTF-8")) { CsvParserSettings settings = new CsvParserSettings(); settings.setProcessor(new BatchedColumnProcessor(5) { @Override public void batchProcessed(int rowsInThisBatch) {} }); CsvParser parser = new CsvParser(settings); List parsedRows = parser.parseAll(inputReader); return parsedRows; } catch (IOException e) { // handle exception }

Per utilizzare questo elaboratore di righe, lo definiamo nel nostro CsvParserSettings e quindi tutto ciò che dobbiamo fare è chiamare parseAll .

3.4. Lettura e scrittura in Java Beans

L'elenco degli array di stringhe va bene, ma spesso lavoriamo con i dati nei Java bean. Univocity consente anche di leggere e scrivere in Java bean appositamente annotati.

Definiamo un bean Product con le annotazioni Univocity:

public class Product { @Parsed(field = "product_no") private String productNumber; @Parsed private String description; @Parsed(field = "unit_price") private float unitPrice; // getters and setters }

L'annotazione principale è l' annotazione @Parsed .

Se l'intestazione della nostra colonna corrisponde al nome del campo, possiamo usare @Parsed senza alcun valore specificato. Se l'intestazione della nostra colonna è diversa dal nome del campo, possiamo specificare l'intestazione della colonna utilizzando la proprietà del campo .

Ora che abbiamo definito il nostro bean Product , leggiamo il nostro file CSV al suo interno:

try (Reader inputReader = new InputStreamReader(new FileInputStream( new File("src/test/resources/productList.csv")), "UTF-8")) { BeanListProcessor rowProcessor = new BeanListProcessor(Product.class); CsvParserSettings settings = new CsvParserSettings(); settings.setHeaderExtractionEnabled(true); settings.setProcessor(rowProcessor); CsvParser parser = new CsvParser(settings); parser.parse(inputReader); return rowProcessor.getBeans(); } catch (IOException e) { // handle exception }

Per prima cosa abbiamo costruito un processore di riga speciale, BeanListProcessor, con la nostra classe annotata. Quindi, lo abbiamo fornito a CsvParserSettings e lo abbiamo utilizzato per leggere un elenco di prodotti .

Quindi, scriviamo il nostro elenco di prodotti in un file a larghezza fissa:

try (Writer outputWriter = new OutputStreamWriter(new FileOutputStream(new File(outputPath)), "UTF-8")) { BeanWriterProcessor rowProcessor = new BeanWriterProcessor(Product.class); FixedWidthFields fieldLengths = new FixedWidthFields(8, 30, 10); FixedWidthWriterSettings settings = new FixedWidthWriterSettings(fieldLengths); settings.setHeaders("product_no", "description", "unit_price"); settings.setRowWriterProcessor(rowProcessor); FixedWidthWriter writer = new FixedWidthWriter(outputWriter, settings); writer.writeHeaders(); for (Product product : products) { writer.processRecord(product); } writer.close(); return true; } catch (IOException e) { // handle exception }

La differenza notevole è che stiamo specificando le intestazioni delle nostre colonne nelle nostre impostazioni.

4. Impostazioni

Univocity ha una serie di impostazioni che possiamo applicare ai parser. Come abbiamo visto in precedenza, possiamo usare le impostazioni per applicare un elaboratore di riga ai parser.

Ci sono molte altre impostazioni che possono essere modificate in base alle nostre esigenze. Sebbene molte delle configurazioni siano comuni ai tre tipi di file, ogni parser ha anche impostazioni specifiche del formato.

Regoliamo le nostre impostazioni del parser CSV per porre alcuni limiti ai dati che stiamo leggendo:

CsvParserSettings settings = new CsvParserSettings(); settings.setMaxCharsPerColumn(100); settings.setMaxColumns(50); CsvParser parser = new CsvParser(new CsvParserSettings());

5. conclusione

In questo rapido tutorial, abbiamo appreso le basi dell'analisi dei file utilizzando la libreria Univocity.

Abbiamo imparato a leggere e scrivere file sia in elenchi di array di stringhe che in Java bean. Prima di entrare nei Java bean, abbiamo dato una rapida occhiata all'utilizzo di diversi processori di riga. Infine, abbiamo toccato brevemente come personalizzare le impostazioni.

Come sempre, il codice sorgente è disponibile su GitHub.