fbpx
Responsive Ad Area
Home » Blog » Reading and Writing delimited files using Java

Share This Post

Blog Role / Java / Tutorial

Delimited Text Files

Pipe Delimited Files

Delimited files are files where data is separated by some symbol or contained by some symbols. Each line is usually columns of data fields. So the entire file ends up being and looking much like a database table. Popular delimiters are pipe | comma , and CSV “”,””,”” delimited. But you could certainly use any method you want. I usually use | because in multiple rows it looks like a vertical line separating columns.

Working with Java and Files Tutorial Trail
Reading Writing FilesProperty Files

 

Data Types

Next, we will want to be able to get data from a text file. Java has some basic data types.

  • String
  • int
  • float
  • boolean

And after that

  • byte
  • short
  • long
  • double
  • char

And we will use the Date object which is deprecated but we will use it anyway in this example.

Example Records

We have already worked with single line strings in part 1. We can store one data type per line or more than one data type per line. There are different ways to do this. It’s helpful if we know the order of the data types being stored. For example, you could store a file of a single data type so that each line is an int or float. But generally you want different types of data in the same file. And generally in a record format. A record is a list of data types in a certain order. For example. An expense tracking record might be.

  • Date
  • Expense Note
  • Amount

An address book might be.

  • Name
  • Address
  • City
  • State
  • Zip

Types of Delimiting

We could simply put each data type on one line in the file and add record after record one after another. This might be a simpler coding but it’s not easy to read or edit as a text file. An XML file would be nice here but we are not working with XML at the moment. A delimited file works better for this application. And there are different ways to delimit a file. I like pipe delimited using the | symbol. also, delimited is common or “,” delimited.

Pipe Delimited
10/2/18|Coke Vending|1.75
10/3/18|Steak Meal|17.52
10/4/18|Gas for Van|54.13

Comma Delimited
10/2/18,Coke Vending,1.75
10/3/18,Steak Meal,17.52
10/4/18,Gas for Van,54.13

Quote Comma Delimited
“10/2/18″,”Coke Vending”,”1.75″
“10/3/18″,”Steak Meal”,”17.52″
“10/4/18″,”Gas for Van”,”54.13″

Another way we might store data is name-value pairs. Java Properties class does this for us. But for example purposes, I will code this myself. Commonly state or configuration data is stored this way. Or maybe statistics for a report. Or let’s say we have a video game.

userName=John
password=1234abcd
money=1125.25
level=5;
magic=false;

And yet another interesting way that is probably not typical is row and column based storage like a spreadsheet. This could be good for storing reports or statics.

Expense|Amount|Food|5.32||
||Gas|45.22||
||Hair Cut|15.23|Weekly|Monthly
||Total|65.77|235.12|2334.23

Parse the lines

The source below simply demonstrates how to parse the lines of the file.

import java.io.*;
import java.util.regex.*;

public class AFileReader {
 private static String aFileName = "textfile1.txt";
  public static void main(String[] args) {
  try (BufferedReader br = new BufferedReader(new FileReader(aFileName))) {
   String aLine;
   while ((aLine = br.readLine()) != null) {
 String[] dataRecord=aLine.split(Pattern.quote("|"));
 for(int i=0;i<dataRecord.length;i++)
  System.out.println(dataRecord[i]);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

Parse the fields

Next, we will convert the same data from strings to given data types and output the results. I also added a couple of fields.

10/2/18|Coke Vending|1.75|100|true
10/3/18|Steak Meal|17.52|102|false
10/4/18|Gas for Van|54.13|508|true

Next, we parse the delimited lines and rebuild as output without the pipes. After this, we will save the data back to a disk file.
This sets us up for altering and adding to the data and saving.

import java.io.*;
import java.util.regex.*;
import java.util.*;
import java.text.*;

public class AFileReader {
 private static String aFileName = "textfile1.txt";
 public static void main(String[] args) {
  Date date=null;
  String note="";
  float amount=0.0f;
  int account=0;
  boolean active=false;
  SimpleDateFormat dateFormat=null;
  try (BufferedReader br = new BufferedReader(new FileReader(aFileName))) {
   String aLine;
 while ((aLine = br.readLine()) != null) {
  String[] dataRecord=aLine.split(Pattern.quote("|"));
  for(int i=0;i<dataRecord.length;i++){
   if(i==0) date=new Date(dataRecord[i]);
   if(i==1) note=dataRecord[i];
   if(i==2) amount=Float.parseFloat(dataRecord[i]);
   if(i==3) account=Integer.parseInt(dataRecord[i]);
   if(i==4) active=Boolean.parseBoolean(dataRecord[i]);
  }
   dateFormat = new SimpleDateFormat("dd/MM/yy");
 System.out.println(dateFormat.format(date)+" "+note+" "+amount+" "+account+" "+((active)?"Active":"Not Active"));
 }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
}

Read in and Write it out to a File

02/10/18 Coke Vending 1.75 100 Active
03/10/18 Steak Meal 17.52 102 Not Active
04/10/18 Gas for Van 54.13 508 Active

Next, we read it in and write it back out to a different file to show that it indeed worked. Though you would see that it worked if written to the same file in this case because in the original file the date was written as 10/2/18 and in the output file 10/02/18 with leading 0 on the day.

import java.io.*;
import java.util.regex.*;
import java.util.*;
import java.text.*;

public class AFileReaderWriter {
 private static String aFileName = "textfile1.txt";
 private static String outputFileName = "textfile2.txt";
 public static void main(String[] args) {
  String aLine=null;
  ArrayList<String> lines=new ArrayList<String>();
  Date date=null;
  String note="";
  float amount=0.0f;
  int account=0;
  boolean active=false;
  SimpleDateFormat dateFormat=null;
  try (BufferedReader br = new BufferedReader(new FileReader(aFileName))) {
  
 while ((aLine = br.readLine()) != null) {
  String[] dataRecord=aLine.split(Pattern.quote("|"));
  for(int i=0;i<dataRecord.length;i++){
   if(i==0) date=new Date(dataRecord[i]);
   if(i==1) note=dataRecord[i];
   if(i==2) amount=Float.parseFloat(dataRecord[i]);
   if(i==3) account=Integer.parseInt(dataRecord[i]);
   if(i==4) active=Boolean.parseBoolean(dataRecord[i]);
  }
  dateFormat = new SimpleDateFormat("MM/dd/yy");
  aLine=dateFormat.format(date)+"|"+note+"|"+amount+"|"+account+"|"+active+"\n";
  lines.add(aLine);
 }
   } catch (IOException e) {
    e.printStackTrace();
   }
   AFileReaderWriter frw= new AFileReaderWriter();
   frw.write(lines);
  } 
  public void write(ArrayList<String> lines) {
   try (BufferedWriter bw = new BufferedWriter(new FileWriter(outputFileName))) {
    Iterator<String> linesIterator = lines.iterator();
    while(linesIterator.hasNext())
     bw.write(linesIterator.next());
   } catch (IOException e) {
    e.printStackTrace();
   }
 }
}
10/02/18|Coke Vending|1.75|100|true
10/03/18|Steak Meal|17.52|102|false
10/04/18|Gas for Van|54.13|508|true

Expense Record Object

Next, we could make an object to hold each records data and to convert it to a line and use an ArrayList of this object. Should we call it RecordSet? Naw how about ExpenseRecord.

 

import java.io.*;
import java.util.regex.*;
import java.util.*;
import java.text.*;

public class RecordReaderWriter {
 private static String aFileName = "textfile1.txt";
 private static String outputFileName = "textfile3.txt";
 public class ExpenseRecord{
  Date date=null;
  String note="";
  float amount=0.0f;
  int account=0;
  boolean active=false;
  public String toString(){
   SimpleDateFormat dateFormat=null;
   dateFormat = new SimpleDateFormat("MM/dd/yy");  
   return dateFormat.format(date)+"|"+note+"|"+amount+"|"+account+"|"+active+"\n";
  }
 }
 public static void main(String[] args) {
  String aLine=null;
  RecordReaderWriter rrw = new RecordReaderWriter();
  ArrayList<ExpenseRecord> records=new ArrayList<ExpenseRecord>();
  try (BufferedReader br = new BufferedReader(new FileReader(aFileName))) {
 while ((aLine = br.readLine()) != null) {
  String[] dataRecord=aLine.split(Pattern.quote("|"));
  ExpenseRecord expense= rrw.new ExpenseRecord();
  for(int i=0;i<dataRecord.length;i++){
   
   if(i==0) expense.date=new Date(dataRecord[i]);
   if(i==1) expense.note=dataRecord[i];
   if(i==2) expense.amount=Float.parseFloat(dataRecord[i]);
   if(i==3) expense.account=Integer.parseInt(dataRecord[i]);
   if(i==4) expense.active=Boolean.parseBoolean(dataRecord[i]);
  }	 
  records.add(expense);
 }
   } catch (IOException e) {
    e.printStackTrace();
   }
   rrw.write(records);
  } 
  public void write(ArrayList<ExpenseRecord> expenseRecords) {
   try (BufferedWriter bw = new BufferedWriter(new FileWriter(outputFileName))) {
    Iterator<ExpenseRecord> expenseRecordsIterator = expenseRecords.iterator();
    while(expenseRecordsIterator.hasNext())
     bw.write(expenseRecordsIterator.next().toString());
   } catch (IOException e) {
    e.printStackTrace();
   }
 }
}

 

What Else?

The next thing we could do is to move the data type parsing into the ExpenseRecord class using setters and getters. After that, we could write examples of altering that data within records and rewriting the file with updates. And after that use a GUI or Web application interface to allow editing of records. Java has built-in searching and sorting functions if you look for them. So we have built a simple flat file database. If your application is simple why use JDBC and SQL. It could be overkill. On the other hand, if you foresee a day when the application will grow to need that, this code will become unused. The data will still port easily into any database. In the next article, we will work on making our own property files for storing name and value pairs. I may add articles to this one someday to include other formats as we discussed including CSV, comma delimited and fixed-width text files.

 

 

Share This Post

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>