Saturday, April 11, 2009

Carriage Returns

Recently, I stumbled upon (literally) an article written by Chad W. L. Whitacre discussing a use for the infamously useless carriage return. Any programmer who has worked with direct input to/from file buffers has probably encountered a character that accompanies the newline character on some file systems. The usual sequence NTFS uses to terminate a line and move the internal pointer to the beginning of the next line is \n\r, where \n writes a null line terminator at the current position (effectively moving the pointer to the next line), and \r writes a carriage return.

If you stop to think about it, it makes sense. When you begin a new line, you want to make sure the internal pointer is writing to a fresh, blank line. So, first you move to the next line (via a newline character), then erase everything on the current line (via a carriage return). Beyond file input, Chad found that the carriage return could be used to erase data on the current line of a system buffer as well! In his article, he talks about using this technique in a TTY shell to make an updating progress bar. I thought I would take it a step further and see if it was implementable in a Java command line program. Sure enough, it works! The following is a basic program that uses a progress bar that updates as the program runs:

import java.io.*;

class progressbar
{
public static void main(String[] args)
{
System.out.println("Running a really long loop...");

// How many times the loop should run
int runcount = 500;

// Prepare the progress meter
System.out.print("[0/" + runcount + "]");

for (int i = 0; i < runcount; i++)
{
// Code that takes longer than a millisecond to execute goes here

// Update the progress meter
System.out.print("\r[" + (i+1) + "/" + runcount + "]");
}

System.out.println("\rdone!");
}
}


Now no one has an excuse to not have progress displays in their programs! :)