Reminder: we have moved to GitHub .
We have two branches: 3_4_branch which remains JDK 1.5 and master/4_x which is JDK8. New development will be limited to master.
January 6, 2019: FlatPack 4.0.4 is released, see the change log
FlatPack came out of the frustration of having to mix file parsing logic with business logic.
FlatPack on SourceForge: a Java (1.8+) flat file parser that handles CSV (including values containing ','), fixed length and custom delimiters. The formats can be configured in XML, it is fast and released under Apache license 2.0.
Starting at release 3.1, FlatPack introduces exporters via the writer package. This mechanism allows you to export a DataSet to a fixed length or delimited format. A big thank you to Dirk and Holger from the Mule project for the initial code contribution. FlatPack should integrate nicely with Mule, the open source choice for integration and SOA.
Substrings in a fixed width parse can be daunting to deal with when trying to analyze what existing code is doing, and what about when you have no comments...
We also provide delimited file parsing ; works with any delimiter / qualifier, multiline records, delimiter or qualifier allowed in column value.
A manual is available as Word document or a PDF .
FlatPack is part of the ObjectLab Kit family.
It parses or creates Delimited files (e.g. CSV) or Fixed Width 'files'.
There is more to it than one could imagine at first sight:
Basic Steps
package net.sf.flatpack; | |
import java.io.StringReader; | |
import java.math.BigDecimal; | |
import java.util.List; | |
import java.util.stream.Collectors; | |
import junit.framework.TestCase; | |
/** | |
* JDK 8 Streaming test. | |
* @author Benoit Xhenseval | |
*/ | |
public class StreamingTest extends TestCase { | |
private static class Test { | |
private String itemName; | |
private BigDecimal price; | |
public String getItemName() { return itemName; } | |
public void setItemName(final String itemName) { this.itemName = itemName; } | |
public BigDecimal getPrice() { return price; } | |
public void setPrice(final BigDecimal price) { this.price = price; } | |
} | |
public void testContains() { | |
final String cols = "item,price,purchaseDate\r\n"// | |
+ "MacBook,1890.20,20140523\r\n"// | |
+ "Surface3,850.00,20140524\r\n"// | |
; | |
final Parser p = DefaultParserFactory.newCsvParser(new StringReader(cols)); | |
final List<Test> ds = p.stream() // | |
.map(t -> { | |
final Test r = new Test(); | |
r.setItemName(t.getString("item")); | |
r.setPrice(t.getBigDecimal("price")); | |
return r; | |
})// Mapping from Record to Test | |
.filter(t -> "Surface3".equals(t.getItemName())) // only keep the Surface3 (why???) | |
.collect(Collectors.toList()); | |
// test record 1 with Data in file! | |
assertEquals("Size", 1, ds.size()); | |
final Test test = ds.get(0); | |
assertEquals("Item", "Surface3", test.getItemName()); | |
assertTrue("Price", new BigDecimal("850").compareTo(test.getPrice()) == 0); | |
} | |
} |
package net.sf.flatpack.xml; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import net.sf.flatpack.Parser; | |
import net.sf.flatpack.brparse.BuffReaderParseFactory; | |
public class TestLoad { | |
public static void main(String[] args) throws FileNotFoundException { | |
// use BuffReaderParseFactory for Buffered Reader --> Able to handle LARGE files. | |
final Parser parser = BuffReaderParseFactory.getInstance().newDelimitedParser(new FileReader("My large TAB Delimited file"), '\t', '"'); | |
parser.parseAsStream().stream().forEach(ds -> { | |
ds.getString("column1"); | |
}); | |
} | |
} |
// Obtain the proper parser for your needs: basic CSV Parser with column Header Parser parser = CsvParserFactory.newForwardCsvParser(new FileReader("DataFile.csv")); //obtain DataSet StreamingDataSet ds = parser.parseAsStream(); while (ds.next()){ //loop through file Record record = ds.getRecord(); // immutable object, you can give it to a thread. String value = record.getString("mycolumnName"); // columns name are case INsensitive }
//Obtain the proper parser for your needs Parser parser = DefaultParserFactory.getInstance().newDelimitedParser( new FileReader("map.fpmap.xml"), //xml column mapping new FileReader("DataFile.txt"), //txt file to parse ',', //delimiter '"', //text qualfier false); //ignore the first record (may need to be done if first record contain column names) //obtain DataSet DataSet ds = parser.parse(); while (ds.next()){ //loop through file ds.getString("mycolumnName"); }
//Obtain the proper parser for your needs Parser parser = DefaultParserFactory.getInstance().newDelimitedParser( new FileReader("DataFile.txt"), //txt file to parse ',', //delimiter '"'); //text qualifier //obtain DataSet DataSet ds = parser.parse(); while (ds.next()){ //loop through file ds.getString("mycolumnName"); }
//Obtain the proper parser for your needs Parser parser = DefaultParserFactory.getInstance().newFixedLengthParser( new FileReader("map.fpmap.xml"), //fixed with column map new FileReader("DataFile.txt")); //txt file to parse //obtain DataSet DataSet ds = parser.parse(); while (ds.next()){ //loop through file ds.getString("mycolumnName"); }
final String msg = "data data2 data3 data4" //Obtain the proper parser for your needs Parser parser = DefaultParserFactory.getInstance().newFixedLengthParser( new FileReader("map.fpmap.xml"), //fixed with column map to bind col names new StringReader(mag)); //data to parse //obtain DataSet DataSet ds = parser.parse(); while (ds.next()){ //loop through file ds.getString("mycolumnName"); }
Slf4j is utilized to capture logging information that occurred during a parse. By default, this information will be logged to the console. SLF supports the following loggers; log4j, jcl, nop, and jdk1.4. Please go to http://www.slf4j.org to download the proper jar for your logging preference. Here is a typical SLF4j setup: SLF-api-XXX.jar + SLF-MyLoggerPreference.jar + MyLogger.jar (lo4j.jar for example) Here are the steps that would need to be taken for log4j: 1. Install log4j.jar 2. Setup log4j.properties or log4j.xml 3. Install SLF-api-XXX.jar 4. Install SLF-log4j12-XXX.jar