16 august 2018
I thought I'd try something a little unusual for what I do here and share
some code. This isn't great or useful code. It's actually beginner code, in
a sense. I'm used to C, C++, Python, and Bash scripting, but I've known so
many people who habitually write in Java and today I decided to have an
earnest go at it. This little Java program is supposed to immitate the
functionality of cat
, a standard utility on Unix-like systems that simply
outputs text either from the files named as command line arguments, or from
the standard input. (If you need a reference for these terms, I recommend
~brennen's friendly guide on the subject.)
// I only use Apache Commons CLI here instead of args because I
// thought I was going to add a help option, but I haven't
// bothered yet
import org.apache.commons.cli.Options;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
class CatApp {
public static void processBuffer(BufferedReader in) {
while (true) {
try {
String line = in.readLine();
if (line == null){
break;
}
System.out.println(line);
} catch (java.io.IOException e) {
break;
}
}
}
public static void main(String[] args) {
// Parse command line arguments
Options options = new Options();
CommandLineParser parser = new DefaultParser();
CommandLine cl;
try {
cl = parser.parse(options, args);
} catch (ParseException e) {
System.err.println(e.getMessage());
return;
}
List<String> filenames = cl.getArgList();
if (filenames.size() > 0) {
// Attempt to read files to stdout if filenames were supplied
// on the command line.
List<FileReader> files = new ArrayList<FileReader>();
// Iterate over filenames, trying to open a FileReader for each
for(String filename : filenames){
try {
files.add(new FileReader(filename));
} catch (FileNotFoundException e) {
System.err.println("Invalid filename " + filename);
return;
}
}
for (FileReader file : files)
{
processBuffer(new BufferedReader(file));
}
} else {
// If no filenames were supplied on the command line, read from
// the standard input instead.
processBuffer(new BufferedReader(new InputStreamReader(System.in)));
}
}
}
I don't know if I'm going to do more in Java anytime soon. My coworkers
thought it was funny that I'd try it, as they have an aversion to using the
language, probably because it doesn't fit so well into their workflows
which center mostly on automation with Python and Ansible. Also, in the
end, because I invoked a third-party library, the .class
file I compile
from this can only be run in the Java VM if I specify the location of the
Apache Commons CLI classes, and most of the solutions for packaging the app
in such a way that an end-user can run it without doing this are a little
more involved than, say, just distributing a Python app with import
statements in it.
Attending my first professional conference tomorrow. This will require actually going into the city, which I rarely do. But I'm just there as a student/intern attendee, so I guess I can relax and try to enjoy myself.