Input and Output - Source and Destination

Java IO解决的问题是从一个source读取数据,和写数据到一个destination。在Java中常见的source和destination有下面几种:

  • Files
  • Pipes
  • Network Connections
  •, System.out, System.error
  • In-memory Buffers (e.g. arrays)

这里面除了In-memory Buffers比较特殊,其它的(文件、管道、socket、设备等)其实在操作系统层面已经统一抽象为文件。





open a stream
while more information
    read information
close the stream


open a stream
while more information
    write information
close the stream


  • 二进制流:字节流, 8-bit bytes; InputStream, OutputStream.
  • 文本流:字符流, 16-bit characters; Reader, Writer.


Overview of the stream hierarchy

  • Reader, root in unicode input hierarchy
  • Writer, root in unicode output hierarchy
  • InputStream, root in binary input hierarchy
  • OutputStream, root in binary output hierarchy

所以上面的这两个Reading和Writing的步骤,使用Java IO就是如下的历程:

public class CopyBytes {
    public static void main(String[] args) throws IOException {

        FileInputStream in = null;
        FileOutputStream out = null;

        try {
            in = new FileInputStream("xanadu.txt");
            out = new FileOutputStream("outagain.txt");
            int c;

            while ((c = != -1) {
        } finally {
            if (in != null) {
            if (out != null) {

public class CopyCharacters {
    public static void main(String[] args) throws IOException {

        FileReader inputStream = null;
        FileWriter outputStream = null;

        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");

            int c;
            while ((c = != -1) {
        } finally {
            if (inputStream != null) {
            if (outputStream != null) {


The class hierarchies for readers and writers in Subclasses of Reader and Writer implement specialized streams and are divided into two categories: those that read from or write to data sinks (shaded) and those that perform some sort of processing (unshaded).


The class hierarchies for inputstreams and outputstreams in Subclasses of Inputstream and OutputStream implement specialized streams and are divided into two categories: those that read from or write to data sinks (shaded) and those that perform some sort of processing (unshaded). LineNumberInputStream is deprecated; use LineNumberReader instead.

TIPS InputStream或者Reader 是连接source的桥梁。OutputStream或者Writer是连接destination的桥梁。

Character Streams that Use Byte Streams

因为其实chars就是bytes的编码,所以Character Streams其实底层就是使用了Byte Streams来读取数据,然后按照指定的编码(如果应用没有指定那么就是file.encoding值)进行byte-to-character转换。所以Reader或者Writer的构造函数往往就是接收一个InputStream或者OutputStream,以及对应的编码(character)。如:

Reader reader = new InputStreamReader(inputStream, "UTF-8");
Writer writer = new OutputStreamWriter(outputStream, "UTF-8");

Character streams are often “wrappers” for byte streams. The character stream uses the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes. FileReader, for example, uses FileInputStream, while FileWriter uses FileOutputStream. There are two general-purpose byte-to-character “bridge” streams: InputStreamReader and OutputStreamWriter. Use them to create character streams when there are no prepackaged character stream classes that meet your needs.

Decorator Pattern and Java IO

Two issues with I/O

  • What are you talking to (n).
  • The way you are talking to it (m).

Solution no. 1

  • Make a class for every combination
  • n * m classes, not flexible, hard to extend

Solutions no. 2

  • Java filter streams (decorators) are added dynamically to create the functionality needed.
  • n + m classes
  • Input decorator: FilterInputStream
    • DataInputStream: Full interface for reading built-in types
    • BufferedInputStream: Adds buffering to the stream (do this by default)
    • LineNumberInputStream: Only adds line numbers
    • PushbackInputStream: One-character push pack for scanners (lexers)
  • Output decorator: FilterOutputStream
    • DataOutputStream: Full interface for writing built-in types
    • PrintStream: Allows primitive formatting of data for display (not printf!)
    • BufferedOutputStream: Adds buffering to output (do this by default!)


Reader reader = new BufferedReader(new FileReader(...));
Writer writer = new BufferedWriter(new FileWriter(...));

import*; // [Source:]

public class DataIODemo {
	public static void main(String[] args) throws IOException {
		// where to write to
		DataOutputStream out = new DataOutputStream(
			new FileOutputStream("invoice1.txt"));

		// alternative also using a buffer decorator
		DataOutputStream out = new DataOutputStream(
			new BufferedOutputStream(
				new FileOutputStream("invoice1.txt")));

Java IO的设计目标和类体系结构

Java IO的设计目标如下:

  • File Access
  • Network Access
  • Internal Memory Buffer Access
  • Inter-Thread Communication (Pipes)
  • Buffering
  • Filtering
  • Parsing
  • Reading and Writing Text (Readers / Writers)
  • Reading and Writing Primitive Data (long, int etc.)
  • Reading and Writing Objects




  1. Basic I/O
  2. Java IO Tutorial
  3. The Java I/O System