Saturday, May 12, 2007

Automating simple file management tasks with BeanShell, Part 2

On another occasion, I generated a text dump containing tridimensional data calculated by our system. The dump was formed of three space-separated columns, each row representing one point in 3D space. I wanted to plot that data in Matlab, so I needed to reformat the dump into a set of Matlab matrixes. I fired up jEdit and started writing a BeanShell script, but since the file was rather large (about 40MB), I thought it would pay if I added a bit of multithreading to the script, so it could take advantage of both my notebook's cores.

You can see below the result, which nicely illustrates how seamlesly BeanShell integrates to the Java platform. I also count it as a very succesful, if limited, experience in multithreading programming: when the script runs, both cores reach 100% usage. Not something I see everyday...


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.regex.Pattern;

String input = "C:/data/point_cloud.data";

class DumpReader extends Thread
{
private int index;

private String header;

private String path;

public DumpReader(int index, String header, String path)
{
this.index = index;
this.header = header;
this.path = path;

setDaemon(true);
start();
}

public void run()
{
BufferedReader data = new BufferedReader(
new FileReader(input)
);

PrintWriter writer = new PrintWriter(new FileWriter(path));
writer.print(header);

Pattern pattern = Pattern.compile("\\s+");
for (String line = ""; (line = data.readLine()) != null;)
{
String[] values = pattern.split(line);
writer.print(values[index] + "\n ");
}

writer.println("];");
writer.flush();
writer.close();
}
}

DumpReader xReader = new DumpReader(0, "X = [ ", "C:/data/x.m");
DumpReader yReader = new DumpReader(1, "Y = [ ", "C:/data/y.m");
DumpReader zReader = new DumpReader(2, "Z = [ ", "C:/data/z.m");