Working with Java IO Streams and File Handling

Understanding Input and Output Streams

Java IO operations revolve around moving data between a program and external sources (like files or networks).

  • Input (Reading): Reading data from a source (e.g., a file on disk) into the Java application as a stream.
  • Output (Writing): Sending data from the Java application out to a destination (e.g., saving to a disk file).

In the context of file transfer:

  • Uploading involves using an Input Stream to bring local data into the program.
  • Downloading involves using an Output Stream to send program data to the local system.

The File Class

The java.io.File class represents file and directory pathnames in an abstract manner. Each instance corresponds to a specific file or folder on the filesystem.

Method Signature Description
File(String pathname) Creates a new File instance by converting the given pathname string into an abstract pathname.
String getName() Returns the name of the file or directory denoted by this abstract pathname.
String getParent() Returns the pathname string of this abstract pathname's parent, or null if this pathname does not name a parent directory.
String getPath() Converts this abstract pathname into a pathname string.
boolean exists() Tests whether the file or directory denoted by this abstract pathname exists.
boolean isDirectory() Tests whether the file denoted by this abstract pathname is a directory.
boolean isFile() Tests whether the file denoted by this abstract pathname is a normal file.
long length() Returns the length of the file denoted by this abstract pathname.
boolean createNewFile() Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.
boolean delete() Deletes the file or directory denoted by this abstract pathname.
boolean mkdir() Creates the directory named by this abstract pathname.
boolean renameTo(File dest) Renames the file denoted by this abstract pathname.

File Operation Example

import java.io.File;
import java.io.IOException;

public class FileDemo {
    public static void main(String[] args) {
        // Example: Checking file properties
        // File source = new File("D:/java/123.png");
        // if (source.exists()) {
        //     System.out.println("Parent: " + source.getParent());
        //     System.out.println("Path: " + source.getPath());
        //     System.out.println("Name: " + source.getName());
        //     System.out.println("Is Directory: " + source.isDirectory());
        //     System.out.println("Is File: " + source.isFile());
        //     System.out.println("Size: " + source.length() + " bytes");
        // }

        // Example: Renaming a file
        File oldFile = new File("D:/java/789.png");
        File renamedFile = new File("D:/java/78910.png");
        if (oldFile.exists()) {
            System.out.println("Rename successful: " + oldFile.renameTo(renamedFile));
        }

        // Example: Creating a new file or directory
        // try {
        //     File newFile = new File("D:/java/newFile.txt");
        //     System.out.println("File created: " + newFile.createNewFile());
        // } catch (IOException e) {
        //     e.printStackTrace();
        // }
    }
}

Stream Classifications

IO streams are categorized based on two factors:

  1. Direction: Input Stream (reading data) vs. Output Stream (writing data).
  2. Data Unit: Byte Stream (handles raw bytes) vs. Character Stream (handles Unicode characters).

Byte Streams: InputStream

InputStream is the superclass of all classes representing an input stream of bytes.

Method Description
int read() Reads the next byte of data from the input stream.
int read(byte[] b) Reads some number of bytes from the input stream and stores them into the buffer array b.
int read(byte[] b, int off, int len) Reads up to len bytes of data from the input stream into an array of bytes, starting at offset off.
int available() Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream.
void close() Closes this input stream and releases any system resources associated with the stream.

Note on Encoding: In standard Java streams, English characters, digits, and punctuation usually ocupy 1 byte, while Chinese characters may occupy 3 bytes (depending on the encoding, e.g., UTF-8).

Reading Bytes (Single Byte)

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

public class ByteReaderDemo {
    public static void main(String[] args) {
        File imgFile = new File("D:\\java\\123.png");
        if (!imgFile.exists()) {
            System.out.println(imgFile.getName() + " not found.");
            return;
        }

        try (InputStream is = new FileInputStream(imgFile)) {
            int byteData;
            while ((byteData = is.read()) != -1) {
                // Processing raw byte data (e.g., printing integer value)
                System.out.println(byteData);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Reading Bytes into a Buffer

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

public class BufferReadDemo {
    public static void main(String[] args) {
        File textFile = new File("D:\\java\\test2.txt");
        if (!textFile.exists()) {
            System.out.println(textFile.getName() + " not found.");
            return;
        }

        try (InputStream is = new FileInputStream(textFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead = is.read(buffer);
            System.out.println("Bytes read: " + bytesRead);
            for (int i = 0; i < bytesRead; i++) {
                System.out.println(buffer[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Reading with Offset

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

public class OffsetReadDemo {
    public static void main(String[] args) {
        File textFile = new File("D:\\java\\test2.txt");
        if (!textFile.exists()) {
            System.out.println(textFile.getName() + " not found.");
            return;
        }

        try (InputStream is = new FileInputStream(textFile)) {
            byte[] buffer = new byte[1024];
            // Read 4 bytes starting at offset 3 in the array
            int bytesRead = is.read(buffer, 3, 4);
            System.out.println("Bytes read: " + bytesRead);
            for (byte b : buffer) {
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Checking Available Bytes

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;

public class AvailableDemo {
    public static void main(String[] args) {
        File textFile = new File("D:\\java\\test2.txt");
        if (!textFile.exists()) {
            System.out.println(textFile.getName() + " not found.");
            return;
        }

        try (InputStream is = new FileInputStream(textFile)) {
            int byteData;
            System.out.println("Initial available: " + is.available());
            while ((byteData = is.read()) != -1) {
                System.out.println("Data: " + byteData + ", Remaining: " + is.available());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Byte Streams: OutputStream

OutputStream is the superclass of all classes representing an output stream of bytes.

Method Description
void write(int b) Writes the specified byte to this output stream.
void write(byte[] b) Writes b.length bytes from the specified byte array to this output stream.
void write(byte[] b, int off, int len) Writes len bytes from the specified byte array starting at offset off to this output stream.
void close() Closes this output stream and releases any system resources associated with the stream.

Writing Bytes to a File

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;

public class ByteWriterDemo {
    public static void main(String[] args) {
        File outFile = new File("D:\\java\\output.txt");
        
        try (OutputStream os = new FileOutputStream(outFile)) {
            // Write a single byte (ASCII for 'C')
            os.write(67);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Writing a Byte Array

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;

public class ArrayWriterDemo {
    public static void main(String[] args) {
        File outFile = new File("D:\\java\\output.txt");
        // Byte values for 'C', 'a', 't', 'B', 'X', 'c', 'd'
        byte[] data = {67, 97, 116, 66, 88, 99, 100};

        try (OutputStream os = new FileOutputStream(outFile)) {
            os.write(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Writing Partial Byte Array

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;

public class PartialWriterDemo {
    public static void main(String[] args) {
        File outFile = new File("D:\\java\\output.txt");
        byte[] data = {67, 97, 116, 66, 88, 99, 100};

        try (OutputStream os = new FileOutputStream(outFile)) {
            // Write 3 bytes starting from index 3 ('B', 'X', 'c')
            os.write(data, 3, 3);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Character Streams vs. Byte Streams

The primary difference is the unit of data:

  • Byte Streams: Handle raw 8-bit bytes. Ideal for binary data (images, audio, class files).
  • Character Streams: Handle 16-bit Unicode characters. Ideal for text data.

Character Streams: Reader

Reader is the abstract class for reading character streams.

Method Description
int read() Reads a single character.
int read(char[] cbuf) Reads characters into an array.
int read(char[] cbuf, int off, int len) Reads characters into a portion of an array.
void close() Closes the stream and releases any system resources asssociated with it.

Reading Characters

import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.io.IOException;

public class CharReaderDemo {
    public static void main(String[] args) {
        File textFile = new File("D:\\java\\test2.txt");
        if (!textFile.exists()) {
            System.out.println(textFile.getName() + " not found.");
            return;
        }

        try (Reader reader = new FileReader(textFile)) {
            int charData;
            while ((charData = reader.read()) != -1) {
                System.out.println(charData); // Prints Unicode value
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Reading Characters into Array with Offset

import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.io.IOException;

public class CharArrayDemo {
    public static void main(String[] args) {
        File textFile = new File("D:\\java\\test2.txt");
        if (!textFile.exists()) {
            System.out.println(textFile.getName() + " not found.");
            return;
        }

        try (Reader reader = new FileReader(textFile)) {
            char[] charBuffer = new char[1024];
            int charsRead = reader.read(charBuffer, 3, 1);
            System.out.println("Characters read: " + charsRead);
            for (char c : charBuffer) {
                System.out.println(c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Character Streams: Writer

Writer is the abstract class for writing to character streams.

Method Description
void write(int c) Writes a single character.
void write(char[] cbuf) Writes an array of characters.
void write(char[] cbuf, int off, int len) Writes a portion of an array of characters.
void write(String str) Writes a string.
void write(String str, int off, int len) Writes a portion of a string.
void close() Closes the stream, flushing it first.

Writing Characters and Strings

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.io.IOException;

public class CharWriterDemo {
    public static void main(String[] args) {
        File outFile = new File("D:\\java\\output.txt");
        char[] greetings = {'你', '好', '世', '界'};
        String message = "我爱写代码";

        try (Writer writer = new FileWriter(outFile)) {
            // Write a portion of the string starting at index 2 ("写代码")
            writer.write(message, 2, 3);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

File Copying Operations

Copying files involves reading from a source and writing to a destination.

Copying Text using Character Streams

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.IOException;

public class TextCopyDemo {
    public static void main(String[] args) {
        File source = new File("D:\\java\\source.txt");
        File dest = new File("D:\\java\\dest.txt");

        try (Reader reader = new FileReader(source);
             Writer writer = new FileWriter(dest)) {
            
            int charData;
            while ((charData = reader.read()) != -1) {
                writer.write(charData);
            }
            System.out.println("Text file copied successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Copying Files using Byte Streams (Universal)

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class BinaryCopyDemo {
    public static void main(String[] args) {
        File source = new File("D:\\java\\source.png");
        File dest = new File("D:\\java\\dest.png");

        try (InputStream is = new FileInputStream(source);
             OutputStream os = new FileOutputStream(dest)) {
            
            int byteData;
            while ((byteData = is.read()) != -1) {
                os.write(byteData);
            }
            System.out.println("File copied successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Important Note: Use Byte Streams for copying non-text files (like images, PDFs, executables). Character streams may corrupt binary data. For text files, both stream types work, but Character streams are often preferred for proper encoding handling.

Tags: java Java IO InputStream OutputStream reader

Posted on Sun, 23 Aug 2026 16:55:28 +0000 by jasonla