Java - Reading from a File

Java - Reading from a File | Detailed Notes with Examples

 Reading from a File in Java

Reading data from files is one of the most important skills in Java programming, especially for developers working on applications that require data processing, log analysis, configuration loading, user-input persistence, and backend services. Java provides multiple powerful classes for reading files, including FileInputStream, FileReader, BufferedReader, Scanner, Files class (NIO), and BufferedInputStream. This document explains all Java file reading methods in great detail using SEO-based keywords such as β€œJava File Handling”, β€œJava File I/O”, β€œJava read text file”, β€œJava read file line by line”, and β€œJava Input Stream”. Each topic contains 10–15 explanatory lines and code examples with outputs.

1. Introduction to Reading Files in Java

Reading files in Java is a key part of Java File I/O operations. Java provides both old-style I/O (java.io) and modern NIO (java.nio) classes for reading text and binary files. When developers work with large applications, reading files efficiently becomes essential for performance. Java provides multiple approaches so that programmers can choose between buffered reading, unbuffered reading, line-by-line reading, and high-performance reading using NIO utilities. File reading is commonly used for loading configuration files, reading logs, reading CSV files, and processing structured or unstructured data. Java ensures secure file access through exception handling using try-catch blocks because reading files may fail due to missing paths, permission issues, or corrupted files. Understanding these concepts ensures strong command over Java File Handling.

2. Reading a File Using FileReader in Java

FileReader is one of the simplest classes used to read text files in Java. It works with character streams and is ideal for reading plain text files such as .txt, .csv, and .log. FileReader reads characters one by one or into a character array. This class is straightforward but not the fastest method, especially for large files, because it lacks buffering. However, it remains an important class for beginners who are learning Java file handling. FileReader throws IOException, so developers must use try-catch or declare throws. This class reads only text files and is not suitable for binary data such as images or audio files. In most applications, FileReader is combined with BufferedReader to improve efficiency. Below is an example demonstrating FileReader usage and output.

Example: Reading Characters Using FileReader


import java.io.FileReader;

public class FileReaderExample {
    public static void main(String[] args) {
        try {
            FileReader fr = new FileReader("sample.txt");
            int ch;

            while ((ch = fr.read()) != -1) {
                System.out.print((char) ch);
            }

            fr.close();
        } catch (Exception e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }
}

Output:


Hello Java FileReader Example
This is sample text content.

3. Reading Files in Java Using BufferedReader

BufferedReader is one of the most efficient and commonly used classes for reading files in Java. It buffers input internally, reducing the number of disk read operations and improving performance significantly. BufferedReader is widely used for reading text line by line using its readLine() method, making it a preferred choice for log file analysis, parsing large datasets, and processing configuration files. It can wrap FileReader, InputStreamReader, or other reader classes. BufferedReader is ideal when developers need a fast, memory-friendly solution for reading large text files. It supports reading full lines, skipping lines, and reading characters or arrays. Since readLine() returns null at end of file, it is easy to detect EOF. BufferedReader requires proper exception handling to avoid runtime issues.

Example: Reading File Line by Line Using BufferedReader


import java.io.BufferedReader;
import java.io.FileReader;

public class BufferedReaderExample {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new FileReader("sample.txt"));
            String line;

            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

            br.close();
        } catch (Exception e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }
}

Output:


Hello Java FileReader Example
This is sample text content.

4. Reading Files Using Scanner in Java

Scanner is one of the most flexible classes for reading files in Java because it supports token-based reading, line reading, pattern matching, and data parsing. Scanner can parse integers, strings, booleans, doubles, and custom patterns, making it useful for reading formatted data such as CSV and log files. It is commonly used in competitive programming, student assignments, and applications that require user-friendly parsing. Scanner internally uses regular expressions to split data, which makes it powerful but slightly slower than BufferedReader for large files. Scanner also offers methods like hasNext(), next(), nextInt(), nextDouble(), and nextLine(), giving developers full control over input handling. Here is an example demonstrating Scanner for reading files.

Example: Reading File Using Scanner


import java.io.File;
import java.util.Scanner;

public class ScannerFileExample {
    public static void main(String[] args) {
        try {
            Scanner sc = new Scanner(new File("sample.txt"));

            while (sc.hasNextLine()) {
                System.out.println(sc.nextLine());
            }

            sc.close();
        } catch (Exception e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }
}

Output:


Hello Java FileReader Example
This is sample text content.

5. Reading Binary Files Using FileInputStream

FileInputStream is used for reading raw binary data such as images, audio, video, PDF files, and binary executable files. Unlike FileReader, FileInputStream handles bytes instead of characters. It is part of the java.io package and is ideal for applications involving data streaming, copying files, or handling multimedia content. Since binary data cannot be displayed directly, developers usually store it in byte arrays or write it to another binary output stream. FileInputStream is also widely used for low-level operations such as custom serialization, encryption, compression, and byte-level manipulation. When reading binary files, developers should handle exceptions to avoid corruption or incomplete reads. The below example demonstrates reading binary data using FileInputStream.

Example: Reading Bytes Using FileInputStream


import java.io.FileInputStream;

public class FileInputStreamExample {
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("image.jpg");
            int data;

            while ((data = fis.read()) != -1) {
                System.out.print(data + " ");
            }

            fis.close();
        } catch (Exception e) {
            System.out.println("Error reading binary file: " + e.getMessage());
        }
    }
}

Output (Sample):


255 216 255 224 0 16 74 70 73 70 0 1 ...

6. Reading Files Using java.nio.file.Files (Modern NIO Approach)

The Java NIO package (New I/O) introduced in Java 7 provides advanced file handling using the Files and Paths classes. These methods are extremely fast, simple, and efficient for small-to-medium files. Developers can read entire files into strings or lists with just one line of code. NIO works at a low level with better control over channels, buffers, and asynchronous file operations, making it ideal for scalable applications. Files.readAllLines(), Files.readString(), and Files.readAllBytes() provide multiple options depending on whether developers need text, individual lines, or raw bytes. NIO also supports reading files using UTF-8 or custom character encodings. Below is an example of reading all lines using Files.readAllLines().

Example: Reading Entire File Using Files Class


import java.nio.file.*;
import java.util.List;

public class FilesReadExample {
    public static void main(String[] args) {
        try {
            List lines = Files.readAllLines(Paths.get("sample.txt"));

            for (String line : lines) {
                System.out.println(line);
            }
        } catch (Exception e) {
            System.out.println("Error reading file using NIO: " + e.getMessage());
        }
    }
}

Output:


Hello Java FileReader Example
This is sample text content.

7. Reading a File Using BufferedInputStream

BufferedInputStream is an efficient class used for reading binary files with buffering capabilities. It significantly improves performance by reducing the number of physical disk reads. BufferedInputStream wraps around FileInputStream and adds a buffer to speed up byte reading operations. It is commonly used for reading large binary files, multimedia content, compressed data, and byte streams. BufferedInputStream reads chunks of bytes at a time instead of reading one byte per request. This approach makes it ideal for performance-sensitive applications such as video streaming, file copying, and server-side data processing. Developers must close streams properly to avoid memory leaks. Below is a working example with output.

Example: Reading Bytes with BufferedInputStream


import java.io.BufferedInputStream;
import java.io.FileInputStream;

public class BufferedInputStreamExample {
    public static void main(String[] args) {
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("image.jpg"));
            int data;

            while ((data = bis.read()) != -1) {
                System.out.print(data + " ");
            }

            bis.close();
        } catch (Exception e) {
            System.out.println("Error reading binary file: " + e.getMessage());
        }
    }
}

Output (Sample):


255 216 255 224 0 16 74 70 73 70 ...

8. Reading File Line-by-Line Using FileInputStream + InputStreamReader

FileInputStream reads bytes, but InputStreamReader converts bytes into characters using a specific charset (default UTF-8). When combined with BufferedReader, this becomes one of the most powerful techniques for reading files that contain Unicode characters such as Hindi, Tamil, Chinese, or emoji. This combination gives developers full control over both encoding and buffering. It is the preferred method for multilingual Java applications, globalized software, and text processing tools. Developers typically choose InputStreamReader when they need to process files with custom or non-default encodings. Below is an example that reads lines using FileInputStream wrapped with InputStreamReader.

Example: FileInputStream + InputStreamReader


import java.io.*;

public class InputStreamReaderExample {
    public static void main(String[] args) {
        try {
            FileInputStream fis = new FileInputStream("sample.txt");
            InputStreamReader isr = new InputStreamReader(fis);
            BufferedReader br = new BufferedReader(isr);

            String line;

            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

            br.close();
        } catch (Exception e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }
}

Output:


Hello Java FileReader Example
This is sample text content.

9. Conclusion

Java provides multiple powerful and flexible ways to read files, depending on whether developers need to read text, binary data, lines, tokens, or entire files. FileReader and BufferedReader are ideal for text files, Scanner is best for parsing data, FileInputStream and BufferedInputStream work with binary content, while NIO's Files class offers fast one-line file reading operations. Understanding all these methods helps developers choose the right technique based on performance, memory usage, file type, and encoding requirements. Mastering Java File I/O is essential for building real-world applications involving data processing, analytics, automation, backend systems, and file-centric utilities.

logo

Java

Beginner 5 Hours
Java - Reading from a File | Detailed Notes with Examples

 Reading from a File in Java

Reading data from files is one of the most important skills in Java programming, especially for developers working on applications that require data processing, log analysis, configuration loading, user-input persistence, and backend services. Java provides multiple powerful classes for reading files, including FileInputStream, FileReader, BufferedReader, Scanner, Files class (NIO), and BufferedInputStream. This document explains all Java file reading methods in great detail using SEO-based keywords such as “Java File Handling”, “Java File I/O”, “Java read text file”, “Java read file line by line”, and “Java Input Stream”. Each topic contains 10–15 explanatory lines and code examples with outputs.

1. Introduction to Reading Files in Java

Reading files in Java is a key part of Java File I/O operations. Java provides both old-style I/O (java.io) and modern NIO (java.nio) classes for reading text and binary files. When developers work with large applications, reading files efficiently becomes essential for performance. Java provides multiple approaches so that programmers can choose between buffered reading, unbuffered reading, line-by-line reading, and high-performance reading using NIO utilities. File reading is commonly used for loading configuration files, reading logs, reading CSV files, and processing structured or unstructured data. Java ensures secure file access through exception handling using try-catch blocks because reading files may fail due to missing paths, permission issues, or corrupted files. Understanding these concepts ensures strong command over Java File Handling.

2. Reading a File Using FileReader in Java

FileReader is one of the simplest classes used to read text files in Java. It works with character streams and is ideal for reading plain text files such as .txt, .csv, and .log. FileReader reads characters one by one or into a character array. This class is straightforward but not the fastest method, especially for large files, because it lacks buffering. However, it remains an important class for beginners who are learning Java file handling. FileReader throws IOException, so developers must use try-catch or declare throws. This class reads only text files and is not suitable for binary data such as images or audio files. In most applications, FileReader is combined with BufferedReader to improve efficiency. Below is an example demonstrating FileReader usage and output.

Example: Reading Characters Using FileReader

import java.io.FileReader; public class FileReaderExample { public static void main(String[] args) { try { FileReader fr = new FileReader("sample.txt"); int ch; while ((ch = fr.read()) != -1) { System.out.print((char) ch); } fr.close(); } catch (Exception e) { System.out.println("Error reading file: " + e.getMessage()); } } }

Output:

Hello Java FileReader Example This is sample text content.

3. Reading Files in Java Using BufferedReader

BufferedReader is one of the most efficient and commonly used classes for reading files in Java. It buffers input internally, reducing the number of disk read operations and improving performance significantly. BufferedReader is widely used for reading text line by line using its readLine() method, making it a preferred choice for log file analysis, parsing large datasets, and processing configuration files. It can wrap FileReader, InputStreamReader, or other reader classes. BufferedReader is ideal when developers need a fast, memory-friendly solution for reading large text files. It supports reading full lines, skipping lines, and reading characters or arrays. Since readLine() returns null at end of file, it is easy to detect EOF. BufferedReader requires proper exception handling to avoid runtime issues.

Example: Reading File Line by Line Using BufferedReader

import java.io.BufferedReader; import java.io.FileReader; public class BufferedReaderExample { public static void main(String[] args) { try { BufferedReader br = new BufferedReader(new FileReader("sample.txt")); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); } catch (Exception e) { System.out.println("Error reading file: " + e.getMessage()); } } }

Output:

Hello Java FileReader Example This is sample text content.

4. Reading Files Using Scanner in Java

Scanner is one of the most flexible classes for reading files in Java because it supports token-based reading, line reading, pattern matching, and data parsing. Scanner can parse integers, strings, booleans, doubles, and custom patterns, making it useful for reading formatted data such as CSV and log files. It is commonly used in competitive programming, student assignments, and applications that require user-friendly parsing. Scanner internally uses regular expressions to split data, which makes it powerful but slightly slower than BufferedReader for large files. Scanner also offers methods like hasNext(), next(), nextInt(), nextDouble(), and nextLine(), giving developers full control over input handling. Here is an example demonstrating Scanner for reading files.

Example: Reading File Using Scanner

import java.io.File; import java.util.Scanner; public class ScannerFileExample { public static void main(String[] args) { try { Scanner sc = new Scanner(new File("sample.txt")); while (sc.hasNextLine()) { System.out.println(sc.nextLine()); } sc.close(); } catch (Exception e) { System.out.println("Error reading file: " + e.getMessage()); } } }

Output:

Hello Java FileReader Example This is sample text content.

5. Reading Binary Files Using FileInputStream

FileInputStream is used for reading raw binary data such as images, audio, video, PDF files, and binary executable files. Unlike FileReader, FileInputStream handles bytes instead of characters. It is part of the java.io package and is ideal for applications involving data streaming, copying files, or handling multimedia content. Since binary data cannot be displayed directly, developers usually store it in byte arrays or write it to another binary output stream. FileInputStream is also widely used for low-level operations such as custom serialization, encryption, compression, and byte-level manipulation. When reading binary files, developers should handle exceptions to avoid corruption or incomplete reads. The below example demonstrates reading binary data using FileInputStream.

Example: Reading Bytes Using FileInputStream

import java.io.FileInputStream; public class FileInputStreamExample { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("image.jpg"); int data; while ((data = fis.read()) != -1) { System.out.print(data + " "); } fis.close(); } catch (Exception e) { System.out.println("Error reading binary file: " + e.getMessage()); } } }

Output (Sample):

255 216 255 224 0 16 74 70 73 70 0 1 ...

6. Reading Files Using java.nio.file.Files (Modern NIO Approach)

The Java NIO package (New I/O) introduced in Java 7 provides advanced file handling using the Files and Paths classes. These methods are extremely fast, simple, and efficient for small-to-medium files. Developers can read entire files into strings or lists with just one line of code. NIO works at a low level with better control over channels, buffers, and asynchronous file operations, making it ideal for scalable applications. Files.readAllLines(), Files.readString(), and Files.readAllBytes() provide multiple options depending on whether developers need text, individual lines, or raw bytes. NIO also supports reading files using UTF-8 or custom character encodings. Below is an example of reading all lines using Files.readAllLines().

Example: Reading Entire File Using Files Class

import java.nio.file.*; import java.util.List; public class FilesReadExample { public static void main(String[] args) { try { List lines = Files.readAllLines(Paths.get("sample.txt")); for (String line : lines) { System.out.println(line); } } catch (Exception e) { System.out.println("Error reading file using NIO: " + e.getMessage()); } } }

Output:

Hello Java FileReader Example This is sample text content.

7. Reading a File Using BufferedInputStream

BufferedInputStream is an efficient class used for reading binary files with buffering capabilities. It significantly improves performance by reducing the number of physical disk reads. BufferedInputStream wraps around FileInputStream and adds a buffer to speed up byte reading operations. It is commonly used for reading large binary files, multimedia content, compressed data, and byte streams. BufferedInputStream reads chunks of bytes at a time instead of reading one byte per request. This approach makes it ideal for performance-sensitive applications such as video streaming, file copying, and server-side data processing. Developers must close streams properly to avoid memory leaks. Below is a working example with output.

Example: Reading Bytes with BufferedInputStream

import java.io.BufferedInputStream; import java.io.FileInputStream; public class BufferedInputStreamExample { public static void main(String[] args) { try { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("image.jpg")); int data; while ((data = bis.read()) != -1) { System.out.print(data + " "); } bis.close(); } catch (Exception e) { System.out.println("Error reading binary file: " + e.getMessage()); } } }

Output (Sample):

255 216 255 224 0 16 74 70 73 70 ...

8. Reading File Line-by-Line Using FileInputStream + InputStreamReader

FileInputStream reads bytes, but InputStreamReader converts bytes into characters using a specific charset (default UTF-8). When combined with BufferedReader, this becomes one of the most powerful techniques for reading files that contain Unicode characters such as Hindi, Tamil, Chinese, or emoji. This combination gives developers full control over both encoding and buffering. It is the preferred method for multilingual Java applications, globalized software, and text processing tools. Developers typically choose InputStreamReader when they need to process files with custom or non-default encodings. Below is an example that reads lines using FileInputStream wrapped with InputStreamReader.

Example: FileInputStream + InputStreamReader

import java.io.*; public class InputStreamReaderExample { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("sample.txt"); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) { System.out.println(line); } br.close(); } catch (Exception e) { System.out.println("Error reading file: " + e.getMessage()); } } }

Output:

Hello Java FileReader Example This is sample text content.

9. Conclusion

Java provides multiple powerful and flexible ways to read files, depending on whether developers need to read text, binary data, lines, tokens, or entire files. FileReader and BufferedReader are ideal for text files, Scanner is best for parsing data, FileInputStream and BufferedInputStream work with binary content, while NIO's Files class offers fast one-line file reading operations. Understanding all these methods helps developers choose the right technique based on performance, memory usage, file type, and encoding requirements. Mastering Java File I/O is essential for building real-world applications involving data processing, analytics, automation, backend systems, and file-centric utilities.

Related Tutorials

Frequently Asked Questions for Java

Java is known for its key features such as object-oriented programming, platform independence, robust exception handling, multithreading capabilities, and automatic garbage collection.

The Java Development Kit (JDK) is a software development kit used to develop Java applications. The Java Runtime Environment (JRE) provides libraries and other resources to run Java applications, while the Java Virtual Machine (JVM) executes Java bytecode.

Java is a high-level, object-oriented programming language known for its platform independence. This means that Java programs can run on any device that has a Java Virtual Machine (JVM) installed, making it versatile across different operating systems.

Deadlock is a situation in multithreading where two or more threads are blocked forever, waiting for each other to release resources.

Functional programming in Java involves writing code using functions, immutability, and higher-order functions, often utilizing features introduced in Java 8.

A process is an independent program in execution, while a thread is a lightweight subprocess that shares resources with other threads within the same process.

The Comparable interface defines a natural ordering for objects, while the Comparator interface defines an external ordering.

The List interface allows duplicate elements and maintains the order of insertion, while the Set interface does not allow duplicates and does not guarantee any specific order.

String is immutable, meaning its value cannot be changed after creation. StringBuffer and StringBuilder are mutable, allowing modifications to their contents. The main difference between them is that StringBuffer is synchronized, making it thread-safe, while StringBuilder is not.

Checked exceptions are exceptions that must be either caught or declared in the method signature, while unchecked exceptions do not require explicit handling.

ArrayList is backed by a dynamic array, providing fast random access but slower insertions and deletions. LinkedList is backed by a doubly-linked list, offering faster insertions and deletions but slower random access.

Autoboxing is the automatic conversion between primitive types and their corresponding wrapper classes. For example, converting an int to Integer.

The 'synchronized' keyword in Java is used to control access to a method or block of code by multiple threads, ensuring that only one thread can execute it at a time.

Multithreading in Java allows concurrent execution of two or more threads, enabling efficient CPU utilization and improved application performance.

A HashMap is a collection class that implements the Map interface, storing key-value pairs. It allows null values and keys and provides constant-time performance for basic operations.

Java achieves platform independence by compiling source code into bytecode, which is executed by the JVM. This allows Java programs to run on any platform that has a compatible JVM.

The Serializable interface provides a default mechanism for serialization, while the Externalizable interface allows for custom serialization behavior.

The 'volatile' keyword in Java indicates that a variable's value will be modified by multiple threads, ensuring that the most up-to-date value is always visible.

Serialization is the process of converting an object into a byte stream, enabling it to be saved to a file or transmitted over a network.

The finalize() method is called by the garbage collector before an object is destroyed, allowing for cleanup operations.

The 'final' keyword in Java is used to define constants, prevent method overriding, and prevent inheritance of classes, ensuring that certain elements remain unchanged.

Garbage collection is the process by which the JVM automatically deletes objects that are no longer reachable, freeing up memory resources.

'throw' is used to explicitly throw an exception, while 'throws' is used in method declarations to specify that a method can throw one or more exceptions.

The 'super' keyword in Java refers to the immediate parent class and is used to access parent class methods, constructors, and variables.

The JVM is responsible for loading, verifying, and executing Java bytecode. It provides an abstraction between the compiled Java program and the underlying hardware, enabling platform independence.

line

Copyrights © 2024 letsupdateskills All rights reserved