Java Input/Output (I/O) Tutorial
Master Java input/output operations: Learn to read user input, write to console, handle files, and format output with practical examples using Scanner, BufferedReader, and System.out methods.
Console I/O
Read/Write to Console
File Handling
Read/Write Files
Scanner Class
Easy Input Parsing
Buffered I/O
Efficient Operations
1. Introduction to Java I/O
Java Input/Output (I/O) operations are essential for interacting with users, reading data from files, writing results, and communicating with other systems. Java provides a rich set of classes in the java.io package for handling I/O operations efficiently.
Types of I/O Streams
- Byte Streams: Handle I/O of raw binary data
- Character Streams: Handle I/O of character data
- Buffered Streams: Improve performance
- Data Streams: Handle primitive data types
- Object Streams: Handle object serialization
Common I/O Classes
System.out- Standard output streamSystem.in- Standard input streamScanner- Text parsing utilityBufferedReader- Efficient text readingFileReader/FileWriter- File operationsPrintWriter- Formatted output
Basic I/O Concept
Java I/O is based on streams - sequences of data. Input streams read data, output streams write data. The standard streams are automatically available to every Java program.
2. Printing Output in Java
Java provides several methods for displaying output to the console. The most common methods are in the System.out object.
public class OutputExamples {
public static void main(String[] args) {
// 1. println() - Prints with new line
System.out.println("Hello, World!");
System.out.println("This is on a new line.");
// 2. print() - Prints without new line
System.out.print("Hello, ");
System.out.print("World! ");
System.out.print("This continues on same line.\n");
// 3. printf() - Formatted output (like C's printf)
String name = "John";
int age = 25;
double salary = 45000.50;
System.out.printf("Name: %s, Age: %d, Salary: $%.2f\n", name, age, salary);
// 4. format() - Alternative to printf
System.out.format("Name: %s | Age: %d | Salary: $%,.2f\n", name, age, salary);
// 5. Printing different data types
System.out.println("Integer: " + 100);
System.out.println("Double: " + 3.14159);
System.out.println("Boolean: " + true);
System.out.println("Character: " + 'A');
// 6. Escape sequences
System.out.println("Tab:\tColumn1\tColumn2");
System.out.println("Backslash: \\");
System.out.println("Double quote: \"Hello\"");
System.out.println("New\nLine");
}
}
| Method | Description | Example |
|---|---|---|
println() |
Prints string with new line | System.out.println("Hello"); |
print() |
Prints string without new line | System.out.print("Hello"); |
printf() |
Formatted printing | System.out.printf("Value: %d", 10); |
format() |
Same as printf | System.out.format("Name: %s", "John"); |
printf Format Specifiers
%d | Decimal integer |
%f | Floating point |
%s | String |
%c | Character |
%b | Boolean |
%n | Platform new line |
Escape Sequences
\n | New line |
\t | Tab |
\\ | Backslash |
\" | Double quote |
\' | Single quote |
\r | Carriage return |
3. Reading Input with Scanner Class
The Scanner class (from java.util package) is the easiest way to read input from keyboard. It can parse primitive types and strings.
import java.util.Scanner;
public class ScannerExample {
public static void main(String[] args) {
// Create Scanner object
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine(); // Read entire line
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // Read integer
System.out.print("Enter your salary: ");
double salary = scanner.nextDouble(); // Read double
System.out.print("Are you employed? (true/false): ");
boolean employed = scanner.nextBoolean(); // Read boolean
// Clear buffer - important after reading primitive types
scanner.nextLine();
System.out.print("Enter your city: ");
String city = scanner.nextLine();
System.out.print("Enter a single character: ");
char grade = scanner.next().charAt(0); // Read first character
// Display all inputs
System.out.println("\n=== User Information ===");
System.out.printf("Name: %s\n", name);
System.out.printf("Age: %d\n", age);
System.out.printf("Salary: $%.2f\n", salary);
System.out.printf("Employed: %b\n", employed);
System.out.printf("City: %s\n", city);
System.out.printf("Grade: %c\n", grade);
// Always close scanner
scanner.close();
}
}
nextLine() Read String
Reads entire line including spaces
nextInt() Read Integer
Reads integer value
nextDouble() Read Double
Reads floating-point value
nextBoolean() Read Boolean
Reads true/false value
next() Read Word
Reads single word (until space)
hasNext() Check Input
Checks if more input available
- Always import
java.util.Scanner - Close scanner with
scanner.close()when done - Use
nextLine()afternextInt(),nextDouble()to clear buffer - Check for available input with
hasNext()methods - Handle
InputMismatchExceptionfor invalid input
4. BufferedReader for Efficient Input
BufferedReader is more efficient than Scanner for reading large amounts of text. It reads characters from an input stream, buffering them for efficiency.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BufferedReaderExample {
public static void main(String[] args) {
// Create BufferedReader
BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));
try {
System.out.print("Enter your name: ");
String name = reader.readLine();
System.out.print("Enter your age: ");
int age = Integer.parseInt(reader.readLine());
System.out.print("Enter your salary: ");
double salary = Double.parseDouble(reader.readLine());
System.out.println("\n=== User Details ===");
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Salary: $" + salary);
// Reading multiple lines until 'exit'
System.out.println("\nEnter multiple lines (type 'exit' to stop):");
String line;
while (!(line = reader.readLine()).equalsIgnoreCase("exit")) {
System.out.println("You typed: " + line);
}
} catch (IOException e) {
System.err.println("Error reading input: " + e.getMessage());
} catch (NumberFormatException e) {
System.err.println("Invalid number format: " + e.getMessage());
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
System.err.println("Error closing reader: " + e.getMessage());
}
}
}
}
| Feature | Scanner | BufferedReader |
|---|---|---|
| Package | java.util |
java.io |
| Performance | Slower for large input | Faster, buffered |
| Parsing | Built-in parsing methods | Manual parsing required |
| Thread Safety | Not thread-safe | Not thread-safe |
| Buffer Size | 1KB | 8KB (default) |
| Use Case | Simple input parsing | Large text reading |
- Use Scanner when: You need to parse different data types, simple console applications, smaller input
- Use BufferedReader when: Reading large files, performance is critical, reading raw text/strings
- Best practice: Scanner for interactive console apps, BufferedReader for file I/O and large data
5. File Input/Output Operations
Java provides multiple classes for reading from and writing to files. Here are the most commonly used approaches.
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class FileWriteExample {
public static void main(String[] args) {
try {
// 1. FileWriter - Basic file writing
FileWriter writer = new FileWriter("output.txt");
writer.write("Hello, File I/O!\n");
writer.write("This is a second line.\n");
writer.close();
// 2. PrintWriter - Formatted file writing
PrintWriter pw = new PrintWriter("data.txt");
pw.println("Name: John Doe");
pw.println("Age: 25");
pw.printf("Salary: $%.2f\n", 45000.50);
pw.close();
// 3. Append to existing file
FileWriter appendWriter = new FileWriter("output.txt", true);
appendWriter.write("This line is appended.\n");
appendWriter.close();
System.out.println("Files written successfully!");
} catch (IOException e) {
System.err.println("Error writing file: " + e.getMessage());
}
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Scanner;
public class FileReadExample {
public static void main(String[] args) {
// Method 1: Using BufferedReader
System.out.println("=== Reading with BufferedReader ===");
try (BufferedReader br = new BufferedReader(new FileReader("output.txt"))) {
String line;
int lineNumber = 1;
while ((line = br.readLine()) != null) {
System.out.println("Line " + lineNumber + ": " + line);
lineNumber++;
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
// Method 2: Using Scanner
System.out.println("\n=== Reading with Scanner ===");
try (Scanner fileScanner = new Scanner(new java.io.File("data.txt"))) {
while (fileScanner.hasNextLine()) {
System.out.println(fileScanner.nextLine());
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
// Method 3: Using FileReader directly
System.out.println("\n=== Reading character by character ===");
try (FileReader reader = new FileReader("output.txt")) {
int character;
while ((character = reader.read()) != -1) {
System.out.print((char) character);
}
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
}
}
}
- Always close files in finally block or use try-with-resources
- Handle
IOExceptionfor file operations - Use buffered streams (
BufferedReader/BufferedWriter) for better performance - Check if file exists before reading
- Use relative paths or get path from user
- Consider file encoding (UTF-8 recommended)
6. Practical I/O Examples
Example 1: Calculator with User Input
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== Simple Calculator ===");
System.out.print("Enter first number: ");
double num1 = scanner.nextDouble();
System.out.print("Enter second number: ");
double num2 = scanner.nextDouble();
System.out.println("\nSelect operation:");
System.out.println("1. Addition (+)");
System.out.println("2. Subtraction (-)");
System.out.println("3. Multiplication (*)");
System.out.println("4. Division (/)");
System.out.print("Enter choice (1-4): ");
int choice = scanner.nextInt();
double result = 0;
String operation = "";
switch (choice) {
case 1:
result = num1 + num2;
operation = "+";
break;
case 2:
result = num1 - num2;
operation = "-";
break;
case 3:
result = num1 * num2;
operation = "*";
break;
case 4:
if (num2 != 0) {
result = num1 / num2;
operation = "/";
} else {
System.out.println("Error: Division by zero!");
scanner.close();
return;
}
break;
default:
System.out.println("Invalid choice!");
scanner.close();
return;
}
System.out.printf("\nResult: %.2f %s %.2f = %.2f\n",
num1, operation, num2, result);
scanner.close();
}
}
Example 2: User Registration System
import java.io.*;
import java.util.Scanner;
public class UserRegistration {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== User Registration ===");
System.out.print("Enter username: ");
String username = scanner.nextLine();
System.out.print("Enter email: ");
String email = scanner.nextLine();
System.out.print("Enter age: ");
int age = scanner.nextInt();
scanner.nextLine(); // Clear buffer
System.out.print("Enter password: ");
String password = scanner.nextLine();
// Save to file
try (PrintWriter writer = new PrintWriter(new FileWriter("users.txt", true))) {
writer.println("=== New User ===");
writer.println("Username: " + username);
writer.println("Email: " + email);
writer.println("Age: " + age);
writer.println("Registration Date: " + new java.util.Date());
writer.println("-------------------");
System.out.println("\nRegistration successful!");
System.out.println("User data saved to users.txt");
} catch (IOException e) {
System.err.println("Error saving user data: " + e.getMessage());
}
// Display saved data
System.out.println("\n=== Registered Users ===");
try (BufferedReader reader = new BufferedReader(new FileReader("users.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
scanner.close();
}
}