Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

Java Tip 64: Get rid of those empty black squares in your text editor

Do you go nuts when your editor shows you unreadable text? The application in this article will help you keep your cool!

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Many programmers spend hours analyzing the code written by excellent programmers to improve their own style and learn new programming tricks. With the upcoming release of JDK 1.2, many who look over the supplied source code will encounter a problem on Windows 95/Windows NT 4.0 systems. After unpacking the sources of the Java API, the standard Windows editor shows unreadable text. If you edit the file Applet.java, for example, you'll see a frame that looks like the following snapshot:

Here, the text lines are just lined up using a black square as line separator symbol. When the chain of lines is getting too long, the output is continued in a new line of the frame.

This Java Tip will help you understand and overcome problems with the representation of the line separator on different systems. It introduces a conversion program called EOLConverter (EOL is an abbreviation for "end of line,") which enables you to get a frame that looks like this:

Now the black squares have vanished into thin air and each line of text is printed on its own line. To see this, just compare the colored regions in this frame to the corresponding regions in the last frame.

Converting the line separator

The conversion of the line separator chosen on the system of the text's author to the line separator used on your system is achieved by the application EOLConverter.java.

Copy this file to the directory housing files you want to convert. Compile the source code by executing the command

javac EOLConverter.java


and start the application by invoking the Java interpreter through the command

java EOLConverter


Please note that the application only converts files with the extensions .htm, .html, .java, and .txt, and that the files in the subdirectories of all levels in your current directory are converted, too.

In the section Analyzing classes, you'll learn how the classes BufferedWriter and BufferedReader in the paackage java.io.* manage the line separator.

In the section Understanding EOLConverter, you'll find a detailed discussion of the statements and the execution flow performed in this application.

Analyzing classes

Now we proceed with the discussion of two essential classes we'll use in our application. The source code for these classes is shipped with the JDK 1.2, and is installed automatically if you don't deactivate the corresponding checkbox during the installation process.

Move to the directory jdk1.2 and unjar the file src.jar by executing the command:

jar -xvf src.jar


You should now find the source files of the API 1.2 in the directory jdk1.2/src.

Edit the file BufferedWriter.java, which is stored in the directory jdk1.2/src/java/io.

  1. At the beginning of the class body, the following string object is defined:

    private String lineSeparator;
    


  2. During the execution of the constructor the object lineSeparator is initialized by

    lineSeparator = (String) java.security.AccessController.doPrivileged(
    
    new sun.security.action.GetPropertyAction("line.separator"));


    Hence the line separator string is defined by the system property line.separator which depends on your system. For example, the value of the line separator is \n on Unix systems and \r\n on Windows systems.

    The character \n represents a line feed (used to roll the paper one line up), and the character \r represents a carriage return (used to move the print head to its initial position). In the past, teletypes (such as normal typewriters -- a combination of a keyboard and a printer) were used to send data directly into the processor of a computer. These characters are an inheritance from the beginning of the computer development and have lost their original meaning today.

  3. To write a line separator to an output stream you use the method newLine, which is defined by:

    public void newLine() throws IOException {
    
    write(lineSeparator); }


    This method writes the value of the line separator on the current system to the output stream.



Now edit the file BufferedReader.java which is stored in the same directory. The analysis of its method readLine is more complicated and is left to the reader. While studying this method you see that, depending on the occurrence of the characters \n or \r, several cases are studied. In Java, a line is considered terminated by any one of the following: a line feed \n, a carriage return \r, or a carriage return followed immediately by a line feed.

You may convert the line separator used in a file by reading its lines using the method readLine of the class BufferedReader and writing its lines back using the methods write and newLine of the class BufferedWriter.

Understanding EOLConverter

We're now ready to move on to a discussion of the specifics of EOLConverter. But first, a look at the source code:

01  import java.io.*;
02  
03  public class EOLConverter implements FilenameFilter {
04  
05    public static void main(String[] arguments) {
06      convertDirectory(".");
07    }
08  
09    public boolean accept(File file, String string) {
10      String path = new String(file.toString() + "?" + string).replace('?', File.separatorChar);
11      boolean b_1 = new File(path).isDirectory();
12      boolean b_2 = string.endsWith(".htm");
13      boolean b_3 = string.endsWith(".html");
14      boolean b_4 = string.endsWith(".java");
15      boolean b_5 = string.endsWith(".txt");
16      return (b_1 || b_2 || b_3 || b_4 || b_5);
17    }
18  
19    public static void convertDirectory(String string) {
20      File directory = new File(string);
21      String[] list = directory.list(new EOLConverter());
22      for (int i = 0; i < list.length; i++) {
23  //      System.out.println(list[i]);
24        String path = new String(string + "?" + list[i]).replace('?', File.separatorChar);
25        if (new File(path).isDirectory()) {
26          convertDirectory(path);
27        } else {
28          convertFile(path);
29        }
30      }
31    }
32  
33    public static void convertFile(String string) {
34      File file_txt = new File(string);
35      File file_tmp = new File(string + ".tmp");
36      try {
37        BufferedReader bufferedreader = new BufferedReader(new FileReader(file_txt));
38        BufferedWriter bufferedwriter = new BufferedWriter(new FileWriter(file_tmp));
39        String line;
40        while ((line = bufferedreader.readLine()) != null) {
41          bufferedwriter.write(line);
42          bufferedwriter.newLine();
43        }
44        bufferedreader.close();
45        bufferedwriter.close();
46        if (file_txt.delete()) {
47          file_tmp.renameTo(file_txt);
48        }
49      } catch (FileNotFoundException filenotfoundexception) {
50      } catch (IOException e) {
51      }
52    }
53  
54  }


Now, on to an explanation of the key lines of code:

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources
  • For more information about the package java.io.*, see the following section of the Java Tutorial http://java.sun.com/docs/books/tutorial/essential/io/index.html
  • Browse JDK 1.2 documentation for further functionality of the BufferedReader class at http://java.sun.com/products/jdk/1.2/docs/api/java/io/BufferedReader.html
  • and the BufferedWriter class at http://java.sun.com/products/jdk/1.2/docs/api/java/io/BufferedWriter.html
  • German readers of JavaWorld are invited to consult the chapter "Eingabe und Ausgabe" of my online course about Java http://www.math.uni-siegen.de/willms/java/index.html