'How to Parse a delimited flat file to a POJO [closed]

Appreciate if someone could point and recommend on how to parse a flat pipe delimited file to JAVA Pojo.

eg. Flat File 0001|XYZ|120

this is required to be read into a POJO having

public class pojo {

private String acct;
private String customer;
private int balance;
}

I can read entire input file as a collection, however, would end up setting each token into a pojo member. Instead, I would like to parse into pojo members. Something similar to CASTOR XML mapping to POJO.

Appreciate any help in this regards. Thanks in advance



Solution 1:[1]

You can use Bean IO. I have been using this extensively.

Configure your XML as something like this

<stream name="employees" format="delimited" strict="true">
  <parser>  
    <property name="delimiter" value="|" />
  </parser>
  <record name="test" class="example.Pojo" minOccurs="1" maxOccurs="1">
      <field name="act" />
      <field name="customer" />
      <field name="balance" type="int" />
    </record>
 </stream>

Refer here for more details.

Solution 2:[2]

OopenCSV http://opencsv.sourceforge.net/ has what you are looking for. Just change the delimiter to | from ,. And you should be all set.

Solution 3:[3]

I would simply read one line at a time, split the values and call the POJO constructor(if not available, create one) e.g.:

   List<pojo> pojoList = new ArrayList<pojo>();
   BufferedReader br = new BufferedReader(new FileReader("FlatFile.txt"));
   String line = "";
   while((line = br.readLine()) != null) {  
       String[] fields = line.split("\|");
       pojo p = new pojo(fields[0], fields[1], fields[2]);
       pojoList.add(p);
   }

Solution 4:[4]

Thanks all for quick responses. Based on Thihara's recommendations, managed to get OPENCSV working ( Thanks to Glen Smith and Kyle Miller for their contributions on Bean Mapping) Get opencsv-2.3.jar from OPENCSV

I am posting full source to benefit others like me.

Input File

/**
     * Input File: acct_os.txt
     * 
     * <pre>
     * 12345|ABC Company|120.45
     * 34567|XYZ Company|45.00
     * 99999|MNC Bank|67.00
     */

/**
 * Bind File to a POJO
 * 
 * @param inputFile
 * @param delim
 * @throws FileNotFoundException
 */
public void bindFileToPojo(String inputFile, char delim) throws FileNotFoundException {

    System.out.println("\n===== Reading to a POJO\n");

    ColumnPositionMappingStrategy<TestCustomerBean> strat = new ColumnPositionMappingStrategy<TestCustomerBean>();
    strat.setType(TestCustomerBean.class);
    /**
     * the fields to bind do in your JavaBean
     */
    String[] columns = new String[] { "acct", "customer", "balance" };
    strat.setColumnMapping(columns);

    CsvToBean<TestCustomerBean> csv = new CsvToBean<TestCustomerBean>();
    /**
     * Read file contents to list using CSVReader
     */
    List<TestCustomerBean> list = csv.parse(strat, new CSVReader(new FileReader(inputFile), delim));
    /**
     * Display column mapping
     */
    displayColumnMapping(strat.getColumnMapping());

    for (TestCustomerBean bean : list) {
        System.out.println("account: ["
                + bean.getAcct()
                    + "] customer: ["
                    + bean.getCustomer()
                    + "] balance: ["
                    + bean.getBalance()
                    + "]");
    }
}

/**
 * Display column mapping
 * 
 * @param columns
 */
private void displayColumnMapping(String[] columns) {
    for (String column : columns) {
        System.out.println("Column Mapping-->" + column);
    }
}

TestCustomerBean (getter/setter omitted)

private String acct;
private String customer;
private Double balance;

Output would be

===== Reading to a POJO

Column Mapping-->acct
Column Mapping-->customer
Column Mapping-->balance
account: [12345] customer: [ABC Company] balance: [120.45]
account: [34567] customer: [XYZ Company] balance: [45.0]
account: [99999] customer: [MNC Bank] balance: [67.0]

Solution 5:[5]

Yet another forum recommended smooth as per suggestions from JayaMohan (Thanks), I am able to get Flat file mapped to a POJO using beanio. You can get beanio

Full source of using beanio

    /**
 * Read inputFile and map to BeanIO Mapping file and bind to pojo
 * 
 * @param inputFile
 * @param mappingFile
 */
public void flatToBeanReader(String inputFile, String mappingFile) {
    /**
     * create a StreamFactory
     */
    StreamFactory factory = StreamFactory.newInstance();
    /**
     * load the mapping file
     */
    factory.load(mappingFile);
    /**
     * use a StreamFactory to create a BeanReader
     */
    BeanReader in = factory.createReader("customers", new File(inputFile));
    TestCustomerBean cust;
    while ((cust = (TestCustomerBean) in.read()) != null) {
        System.out.println("acct: ["
                + cust.getAcct()
                    + "] customer: ["
                    + cust.getCustomer()
                    + "] balance: ["
                    + cust.getBalance()
                    + "]");
    }
    in.close();
}

Mapping File

<?xml version="1.0" encoding="UTF-8"?>
<beanio xmlns="http://www.beanio.org/2012/03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">

    <stream name="customers" format="delimited" strict="false">
        <parser>
            <property name="delimiter" value="|" />
        </parser>
        <record name="cust" class="TestCustomerBean">
            
            <field name="acct" />
            <field name="customer" />
            <field name="balance" type="Double" />
        </record>
    </stream>

</beanio>

Output would be:

acct: [12345] customer: [ABC Company] balance: [120.45]
acct: [34567] customer: [XYZ Company] balance: [45.0]
acct: [99999] customer: [MNC Bank] balance: [67.0]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Thihara
Solution 3 Yogendra Singh
Solution 4 Anand
Solution 5 smilyface