The Byte Stream: InputStream, OutputStream, File I/O, PrintStream & RandomAccessFile
1. Abstract Superclasses of Byte Streams: InputStream & OutputStream
All byte stream classes in java.io descend from two abstract superclasses that handle 8-bit raw bytes:
A. InputStream (Abstract Root Class for Reading Bytes)
Defines the fundamental methods that every byte input stream must implement:
int read(): Reads the next single byte of data from the input stream (returns anintbetween0and255), or returns-1if the End of File (EOF) has been reached!int read(byte[] b): Reads a chunk of bytes into the byte arrayband returns the number of bytes actually read.int available(): Returns the number of bytes currently available for reading without blocking.void close(): Closes the input stream and releases any OS file locks.
B. OutputStream (Abstract Root Class for Writing Bytes)
Defines the fundamental methods that every byte output stream must implement:
void write(int b): Writes a single byte to the output stream.void write(byte[] b): Writes an entire array of bytesbto the output stream.void flush(): Forces any buffered output bytes to be written out immediately to the disk/network.void close(): Closes the output stream and releases system resources.
2. FileInputStream and FileOutputStream
These are the two most commonly used concrete byte stream classes for reading from and writing to actual files on your computer’s hard disk.
A. FileOutputStream (Writing Bytes to a File)
- Used to create a file and write raw byte data into it.
- If the specified file does not exist on disk,
FileOutputStreamautomatically creates a new file! - Constructors:
FileOutputStream fos = new FileOutputStream("data.txt");(Overwrites existing file)FileOutputStream fos = new FileOutputStream("data.txt", true);(Appends to the end of the file becauseappend = true)
B. FileInputStream (Reading Bytes from a File)
- Used to read raw bytes from an existing file on disk (such as a text file, image, or audio file).
- Throws
FileNotFoundExceptionif the file does not exist. - Rule for Reading Loop: Keep calling
int ch = fis.read();inside awhile ((ch = fis.read()) != -1)loop until-1(End of File) is returned!
Complete Program: Writing and Reading a File Using FileOutputStream & FileInputStream
import java.io.*;
public class FileByteStreamDemo {
public static void main(String[] args) {
String fileName = "bca_notes.txt";
// PART 1: Writing data to a file using FileOutputStream
try {
FileOutputStream fos = new FileOutputStream(fileName);
String text = "Java Byte Streams are fast and easy!";
byte[] byteArray = text.getBytes(); // Convert String into byte[]
fos.write(byteArray);
fos.close();
System.out.println("Successfully wrote data to " + fileName);
} catch (IOException e) {
System.out.println("Write Error: " + e);
}
// PART 2: Reading data back from the file using FileInputStream
try {
FileInputStream fis = new FileInputStream(fileName);
System.out.print("File Contents: ");
int byteData;
// Read byte-by-byte until -1 (End Of File) is reached
while ((byteData = fis.read()) != -1) {
System.out.print((char) byteData); // Type-cast byte to char
}
System.out.println();
fis.close();
} catch (IOException e) {
System.out.println("Read Error: " + e);
}
}
}
Output:
Successfully wrote data to bca_notes.txt
File Contents: Java Byte Streams are fast and easy!
3. The PrintStream Class
Have you ever wondered how System.out.println() works? System.out is an object of the java.io.PrintStream class!
- What is
PrintStream?PrintStreamis a byte output stream (subclass ofFilterOutputStream) that adds convenient methods to print any data type (int,float,double,boolean,String,Object) in human-readable text format instead of raw bytes. - 2 Unique Features of
PrintStream:- Never Throws
IOException! Unlike other streams,PrintStreamcatchesIOExceptioninternally and sets an internal error flag that can be checked viacheckError()(that is why you never need to writetry-catcharoundSystem.out.println()!). - Auto-Flushing: Can be configured to flush the output buffer automatically whenever a newline character (
\n) is written.
- Never Throws
- Key Methods:
print(),println(),printf(),format(),checkError().
// Redirecting PrintStream to write formatted output directly into a File!
PrintStream ps = new PrintStream(new FileOutputStream("result.txt"));
ps.println("Student Name: Aarav Sharma");
ps.println("Roll Number : " + 101);
ps.printf("Percentage : %.2f%%\n", 88.5);
ps.close();
4. RandomAccessFile in Java
All standard streams (FileInputStream, FileOutputStream, FileReader) are Sequential Access Streams—meaning you must start at byte 0 and read/write sequentially from beginning to end (like an old cassette tape).
What if you have a huge 1 GB database file and want to jump directly to byte 50,000, read a record, and overwrite it in place? Java provides java.io.RandomAccessFile!
- Reads strictly in one direction: Byte 0 → 1 → 2 → EOF
- Separate classes for Reading and Writing
- Cannot move backwards or jump to middle of file
- Maintains a movable cursor called the File Pointer
- Can jump to ANY byte instantly using
seek(long pos) - Can BOTH Read and Write using the same object!
Key Features of RandomAccessFile:
- Supports Both Reading and Writing: Implements both
DataInputandDataOutputinterfaces in a single class! - Movable File Pointer (
seek): Maintains an internal cursor called the File Pointer (like the cursor in Notepad) that you can move forward or backward to any byte offset usingseek(long bytePosition). - Access Modes in Constructor (
new RandomAccessFile(file, mode)):"r"(Read-Only): Opens the file for reading only."rw"(Read and Write): Opens the file for both reading and writing (creates the file if it doesn’t exist).
Important Methods of RandomAccessFile:
void seek(long pos): Moves the file-pointer offset to byte positionposfrom the beginning of the file.long getFilePointer(): Returns the current byte offset location of the file pointer.long length(): Returns the total length of the file in bytes.readInt(),readUTF(),writeInt(),writeUTF(),read(),write(): Reads and writes primitives or bytes at the current pointer position.
Complete Program Demonstrating RandomAccessFile
import java.io.*;
public class RandomAccessDemo {
public static void main(String[] args) {
try {
// Open file in "rw" (Read + Write) mode
RandomAccessFile raf = new RandomAccessFile("random_demo.txt", "rw");
// 1. Write a string into the file
raf.writeBytes("HELLO_BCA_INDORE");
// 2. Jump directly to byte index 6 using seek(6) ('B' of BCA)
raf.seek(6);
System.out.println("Current Pointer Position: " + raf.getFilePointer());
// 3. Read 3 bytes starting from position 6
byte[] buf = new byte[3];
raf.read(buf);
System.out.println("3 Bytes from index 6 : " + new String(buf)); // Prints: BCA
// 4. Jump back to byte 6 and overwrite "BCA" with "MCA" in-place!
raf.seek(6);
raf.writeBytes("MCA");
// 5. Jump to 0 (start of file) and read the whole modified line
raf.seek(0);
System.out.println("Modified File Content : " + raf.readLine());
raf.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
Output:
Current Pointer Position: 6
3 Bytes from index 6 : BCA
Modified File Content : HELLO_MCA_INDORE
💡 Exam Preparation Tips for DAVV BCA
RandomAccessFileis a very popular 5-mark short note in Unit 5. Always highlight its two access modes ("r"and"rw") and its two pointer methods (seek(long pos)andgetFilePointer()).- In
FileInputStream, remember thatread()returns-1when it reaches the End of File (EOF).