Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Introduction to Java programming, Part 2: Constructs for real-world applications

More-advanced Java language features

J Steven Perry, Principal Consultant, Makoto Consulting Group, Inc.
Photo of J Steven Perry
J. Steven Perry is a software developer, architect, and general Java nut who has been developing software professionally since 1991. His professional interests range from the inner workings of the JVM to UML modeling and everything in between. Steve has a passion for writing and mentoring; he is the author of Java Management Extensions (O'Reilly), Log4j (O'Reilly), and the IBM developerWorks articles "Joda-Time" and OpenID for Java Web applications." In his spare time, he hangs out with his three kids, rides his bike, and teaches yoga.

Summary:  In Part 1 of this tutorial, professional Java™ programmer J. Steven Perry introduced the Java language syntax and libraries you need to write simple Java applications. Part 2, still geared toward developers new to Java application development, introduces the more-sophisticated programming constructs required for building complex, real-world Java applications. Topics covered include exception handling, inheritance and abstraction, regular expressions, generics, Java I/O, and Java serialization.

View more content in this series

Date:  19 Aug 2010
Level:  Introductory PDF:  A4 and Letter (904 KB | 53 pages)Get Adobe® Reader®

Comments:  

I/O

This section is an overview of the java.io package. You'll learn to use some of its tools to collect and manipulate data from a variety of sources.

Working with external data

More often than not, the data you use in your Java programs will come from an external data source, such as a database, direct byte transfer over a socket, or file storage. The Java language gives you many tools to get information from these sources, and most of them are located in the java.io package.


Files

Of all the data sources available to your Java applications, files are the most common and often the most convenient. If you want to read a file in your Java application, you must use streams that parse its incoming bytes into Java language types.

java.io.File is a class that defines a resource on your file system and represents that resource in an abstract way. Creating a File object is easy:

File f = new File("temp.txt");
File f2 = new File("/home/steve/testFile.txt");

The File constructor takes the name of the file it will create. The first call creates a file called temp.txt in the given directory. The second call creates a file in a specific location on my Linux system. You can pass any String to the constructor of File, so long as it is a valid file name for your OS, whether or not the file that it references even exists.

This code asks the newly created File object if the file exists:

File f2 = new File("/home/steve/testFile.txt");
if (f2.exists()) {
 // File exists. Process it...
} else {
 // File doesn't exist. Create it...
 f2.createNewFile();
}

java.io.File has some other handy methods that you can use to delete files, create directories (by passing a directory name as the argument to File's constructor), determine whether a resource is a file, directory, or symbolic link, and more.

The real action of Java I/O is in writing to and reading from data sources, which is where streams come in.


Using streams in Java I/O

You can access files on the file system using streams. At the lowest level, streams allow a program to receive bytes from a source or to send output to a destination. Some streams handle all kinds of 16-bit characters (Reader and Writer types). Others handle only 8-bit bytes (InputStream and OutputStream types). Within these hierarchies are several flavors of streams, all found in the java.io package. At the highest level of abstraction are character streams and byte streams.

Byte streams read (InputStream and subclasses) and write (OutputStream and subclasses) 8-bit bytes. In other words, a byte stream can be considered a more raw type of stream. Here's a summary of two common byte streams and their usage:

  • FileInputStream/FileOutputStream: Reads bytes from a file, writes bytes to a file.
  • ByteArrayInputStream/ByteArrayOutputStream: Reads bytes from an in-memory array, writes bytes to an in-memory array.

Character streams

Character streams read (Reader and its subclasses) and write (Writer and its subclasses) 16-bit characters. Here's a selected listing of character streams and their usage:

  • StringReader/StringWriter: Read and write characters to and from Strings in memory.
  • InputStreamReader/InputStreamWriter (and subclasses FileReader/FileWriter): Form a bridge between byte streams and character streams. The Reader flavors read bytes from a byte stream and convert them to characters. The Writer flavors convert characters to bytes to put them on byte streams.
  • BufferedReader/BufferedWriter: Buffer data while reading or writing another stream, making read and write operations more efficient.

Rather than try to cover streams in their entirety, I'll focus on the recommended streams for reading and writing files. In most cases, these are character streams.

Reading from a File

There are several ways to read from a File. Arguably the simplest approach is to:

  1. Create an InputStreamReader on the File you want to read from.
  2. Call read() to read one character at a time until you reach the end of the file.

Listing 25 is an example in reading from a File:


Listing 25. Reading from a File

Logger log = Logger.getAnonymousLogger();
StringBuilder sb = new StringBuilder();
try {
 InputStream inputStream = new FileInputStream(new File("input.txt"));
 InputStreamReader reader = new InputStreamReader(inputStream);
 try {
   int c = reader.read();
   while (c != -1) {
     sb.append(c);
   }
 } finally {
 reader.close();
 }
} catch (IOException e) {
 log.info("Caught exception while processing file: " + e.getMessage());
}

Writing to a File

As with reading from a File, there are several ways to write to a File. Once again, I'll go with the simplest approach:

  1. Create a FileOutputStream on the File you want to write to.
  2. Call write() to write the character sequence.

Listing 26 is an example of writing to a File:


Listing 26. Writing to a File

Logger log = Logger.getAnonymousLogger();
StringBuilder sb = getStringToWriteSomehow();
try {
 OutputStream outputStream = new FileOutputStream(new File("output.txt"));
 OutputStreamWriter writer = new OutputStreamWriter(outputStream);
 try {
   writer.write(sb.toString());
 } finally {
   writer.close();
 }
} catch (IOException e) {
 log.info("Caught exception while processing file: " + e.getMessage());
}

Buffering streams

Reading and writing character streams one character at a time is not exactly efficient, so in most cases, you'll probably want to use buffered I/O instead. To read from a file using buffered I/O, the code looks just like Listing 25, except that you wrap the InputStreamReader in a BufferedReader, as shown in Listing 27:


Listing 27. Reading from a File with buffered I/O

Logger log = Logger.getAnonymousLogger();
StringBuilder sb = new StringBuilder();
try {
 InputStream inputStream = new FileInputStream(new File("input.txt"));
 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
 try {
   String line = reader.readLine();
   while (line != null) {
     sb.append(line);
     line = reader.readLine();
   }
 } finally {
 reader.close();
 }
} catch (IOException e) {
 log.info("Caught exception while processing file: " + e.getMessage());
}

Writing to a file using buffered I/O is the same: you just wrap the OutputStreamWriter in a BufferedWriter, as shown in Listing 28


Listing 28. Writing to a File with buffered I/O

Logger log = Logger.getAnonymousLogger();
StringBuilder sb = getStringToWriteSomehow();
try {
 OutputStream outputStream = new FileOutputStream(new File("output.txt"));
 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
 try {
   writer.write(sb.toString());
 } finally {
   writer.close();
 }
} catch (IOException e) {
 log.info("Caught exception while processing file: " + e.getMessage());
}

I've merely scratched the surface of what's possible with this essential Java library. On your own, try applying what you've learned about files to other data sources.

10 of 14 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=508383
TutorialTitle=Introduction to Java programming, Part 2: Constructs for real-world applications
publish-date=08192010
author1-email=steve@makotoconsulting.com
author1-email-cc=jaloi@us.ibm.com