Java – Read File Line by Line and Write to Properties File
File I/O is a fundamental skill in Java development. This tutorial covers two common file operations: reading a text file line by line, and writing/reading a .properties configuration file. Both are used constantly in real applications for loading configs, processing logs, and storing settings.
Part 1: Read a File Line by Line
Java provides several ways to read files. We'll cover the three most commonly used: BufferedReader (classic), Files.readAllLines() (simple), and Files.lines() with Stream (modern).
package com.java9r;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
/**
* Three ways to read a file line by line in Java.
* All methods handle the file in src/main/resources/sample.txt
*/
public class ReadFileDemo {
private static final String FILE_PATH = "sample.txt";
public static void main(String[] args) throws IOException {
// Create a sample file to read
Files.write(Paths.get(FILE_PATH),
"Java 8\nJava 9\nJava 10\nJava 11\nJava 17\nJava 21".getBytes());
// --- Method 1: BufferedReader (works in all Java versions) ---
System.out.println("=== Method 1: BufferedReader ===");
try (var reader = new BufferedReader(new FileReader(FILE_PATH))) {
String line;
int lineNum = 1;
while ((line = reader.readLine()) != null) {
System.out.println(lineNum++ + ": " + line);
}
}
// --- Method 2: Files.readAllLines() – entire file into a List ---
System.out.println("\n=== Method 2: Files.readAllLines() ===");
List<String> lines = Files.readAllLines(Paths.get(FILE_PATH), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
System.out.println("Total lines: " + lines.size());
// --- Method 3: Files.lines() – Stream API (memory-efficient for large files) ---
System.out.println("\n=== Method 3: Files.lines() Stream ===");
try (var stream = Files.lines(Paths.get(FILE_PATH), StandardCharsets.UTF_8)) {
stream.filter(l -> l.startsWith("Java 1"))
.sorted()
.forEach(System.out::println);
}
}
}
Expected Output
=== Method 1: BufferedReader ===
1: Java 8
2: Java 9
3: Java 10
4: Java 11
5: Java 17
6: Java 21
=== Method 2: Files.readAllLines() ===
Java 8
Java 9
Java 10
Java 11
Java 17
Java 21
Total lines: 6
=== Method 3: Files.lines() Stream ===
Java 10
Java 11
Java 17
Which Method to Use?
| Method | Best For | Memory |
|---|---|---|
| BufferedReader | Large files, fine control | Low (one line at a time) |
| Files.readAllLines() | Small files, simple code | High (all lines in memory) |
| Files.lines() Stream | Large files + filtering | Low (lazy evaluation) |
Part 2: Write and Read a Properties File
A .properties file stores key-value configuration pairs. Java's java.util.Properties class handles reading and writing these files automatically.
package com.java9r;
import java.io.*;
import java.util.Properties;
/**
* Write and read a Java .properties configuration file.
*/
public class PropertiesFileDemo {
private static final String PROPS_FILE = "app.properties";
public static void main(String[] args) throws IOException {
// --- Write properties to file ---
writeProperties();
// --- Read properties from file ---
readProperties();
// --- Read with default values ---
readWithDefaults();
}
private static void writeProperties() throws IOException {
Properties props = new Properties();
// Set key-value pairs
props.setProperty("db.host", "localhost");
props.setProperty("db.port", "3306");
props.setProperty("db.name", "java9rdb");
props.setProperty("db.username", "root");
props.setProperty("app.name", "Java9R Tutorial");
props.setProperty("app.version", "2.0");
props.setProperty("app.debug", "false");
// Write to file with a comment header
try (var out = new FileOutputStream(PROPS_FILE)) {
props.store(out, "Java9R Application Configuration");
}
System.out.println("Properties written to: " + PROPS_FILE);
}
private static void readProperties() throws IOException {
Properties props = new Properties();
try (var in = new FileInputStream(PROPS_FILE)) {
props.load(in);
}
System.out.println("\n=== Application Config ===");
System.out.println("App name: " + props.getProperty("app.name"));
System.out.println("App version: " + props.getProperty("app.version"));
System.out.println("DB host: " + props.getProperty("db.host"));
System.out.println("DB port: " + props.getProperty("db.port"));
System.out.println("DB name: " + props.getProperty("db.name"));
System.out.println("\nAll properties:");
props.forEach((k, v) -> System.out.println(" " + k + " = " + v));
}
private static void readWithDefaults() throws IOException {
Properties props = new Properties();
try (var in = new FileInputStream(PROPS_FILE)) {
props.load(in);
}
// getProperty(key, defaultValue) – returns default if key not found
String timeout = props.getProperty("db.timeout", "30");
String maxConn = props.getProperty("db.maxConnections", "10");
System.out.println("\n=== With Defaults ===");
System.out.println("DB timeout: " + timeout + "s (default)");
System.out.println("Max connections: " + maxConn + " (default)");
}
}
Expected Output
Properties written to: app.properties
=== Application Config ===
App name: Java9R Tutorial
App version: 2.0
DB host: localhost
DB port: 3306
DB name: java9rdb
All properties:
db.host = localhost
db.port = 3306
db.name = java9rdb
db.username = root
app.name = Java9R Tutorial
app.version = 2.0
app.debug = false
=== With Defaults ===
DB timeout: 30s (default)
Max connections: 10 (default)
Contents of app.properties
#Java9R Application Configuration
#Thu Jun 12 2026 12:00:00 IST
db.host=localhost
db.port=3306
db.name=java9rdb
db.username=root
app.name=Java9R Tutorial
app.version=2.0
app.debug=false
Sort File Contents
import java.nio.file.*;
import java.util.stream.Collectors;
// Read, sort, and write back
Path path = Paths.get("names.txt");
var sorted = Files.lines(path)
.sorted()
.collect(Collectors.joining("\n"));
Files.writeString(path, sorted);
System.out.println("File sorted successfully.");
Summary
For reading files line by line, use BufferedReader for large files, Files.readAllLines() for small files where you need all lines as a list, and Files.lines() for large files with Stream-based filtering. For configuration files, java.util.Properties handles the standard key=value format with comment support, and the getProperty(key, defaultValue) overload makes it easy to define fallback values for missing settings.
Comments