04 June 2008
We've been using Java and Ruby for work, and we've recently been asked to look more toward Groovy where we had been using Ruby, so I rewrote a useful little iconv script which we use to re-encode large volumes of data (which the GNU iconv doesn't seem to want to handle).
For illustration, here are the implementations I wrote:
Java (40 lines):
import java.io.*;
public class Iconv {
public static void main(final String[] args) throws Exception {
if (args.length < 2) {
System.out.println(
"Usage: Iconv <in>:<encoding> <out>:<encoding>");
return;
}
final String[] ins = args[0].split(":");
final String[] outs = args[1].split(":");
final String inFile = ins[0];
final String inEnc = ins[1];
final String outFile = outs[0];
final String outEnc = outs[1];
Writer writer = null;
try {
writer = new OutputStreamWriter(
new FileOutputStream(outFile), outEnc);
Reader reader = null;
try {
reader = new InputStreamReader(
new FileInputStream(inFile), inEnc);
Integer character = null;
while ((character = reader.read()) >= 0) {
writer.write(character);
}
} finally {
if (reader != null)
reader.close();
}
} finally {
if (writer != null)
writer.close();
}
}
}
Ruby (20 lines):
#!/usr/bin/env jruby
require 'iconv'
require 'fileutils'
if ARGV.size < 2 then
puts "Usage: iconv.rb <from>:<enc> <to>:<enc>"
exit
end
in_file, in_enc = ARGV[0].split(":")
out_file, out_enc = ARGV[1].split(":")
Iconv.open(out_enc, in_enc) do |conv|
File.open(out_file, 'w') do |out|
File.open(in_file, 'r').each_line do |line|
out.write(conv.iconv(line))
end
end
end
Groovy (19 lines):
#!/usr/bin/env groovy
if (args.size() < 2) {
println "Usage: iconv.groovy <from>:<enc> <to>:<enc>"
return
}
final ins = args[0].split(":")
final outs = args[1].split(":")
final from = ins[0]
final fromEnc = ins[1]
final to = outs[0]
final toEnc = outs[1]
new FileOutputStream(to).withWriter(toEnc) { writer ->
new FileInputStream(from).withReader(fromEnc) { reader ->
writer << reader
}
}
Using the Groovy 1.6 beta, I could have used the new left-side array assignment syntax to shorten the groovy version to 15 lines:
...
[from, fromEnc] = args[0].split(":")
...
I had initially set out to skip over Groovy and just learn Ruby, as I had viewed Groovy as a sort of compromise -- Ruby would be the real twist of the mind, but alas, my neural pathways seem a bit more rigid than I had hoped. I can think a little quicker in Groovy than Ruby and get a few things done. Groovy is also a bit more compatible with the work directives handed down from on high -- we want to be a Java shop.
Update (2008-06-04): I updated the code above to reflect some comments. To be complete, the Java code should null check the streams it's trying to close in the finally blocks.
Filed Under: Technology Java Computers Work Groovy