File API
Java file I/O — the modern java.nio.file.Files API vs legacy java.io.File, reading, writing, and traversing the filesystem.
Last reviewed: January 2025
🔍 What Is It?
Modern API (use this):
- →
java.nio.file.Path— represents a file or directory path (replaces java.io.File) - →
java.nio.file.Files— utility class with all file operations - →
java.nio.file.Paths— factory for Path objects (Java 7-10) - →
Path.of()— factory for Path objects (Java 11+, preferred)
Legacy API (avoid in new code):
- →
java.io.File— old path representation - →
java.io.FileInputStream/FileOutputStream— byte streams - →
java.io.FileReader/FileWriter— character streams (no charset control!) - →
java.io.BufferedReader/BufferedWriter— buffered wrappers
Key Files methods:
- →readString(path) / readAllBytes(path) / readAllLines(path) — read entire file
- →writeString(path, content) / write(path, bytes) — write entire file
- →lines(path) — Stream<String> of lines (lazy)
- →copy(source, target) / move(source, target) / delete(path)
- →createFile(path) / createDirectory(path) / createDirectories(path)
- →exists(path) / isDirectory(path) / isRegularFile(path)
- →walk(path) — Stream<Path> of all files recursively
- →list(path) — Stream<Path> of immediate children
🎯 Why Do We Need It?
The legacy java.io.File API has many problems:
- →Methods return false instead of throwing exceptions (hard to diagnose failures)
- →No charset control in FileReader/FileWriter (uses platform default — dangerous!)
- →No atomic operations
- →No symbolic link support
- →No file metadata (owner, permissions, timestamps)
java.nio.file solves all of these:
- →Throws IOException with clear messages
- →Explicit charset everywhere
- →StandardCopyOption.ATOMIC_MOVE for atomic file replacement
- →Full symbolic link and attribute support
🏗️ What Happens in Real Projects?
Common enterprise use cases:
- →Reading configuration files (YAML, JSON, properties)
- →Writing reports and exports (CSV, PDF, Excel)
- →Processing uploaded files
- →Log file analysis
- →File-based data pipelines
⚙️ How It Works
Path vs File:
// Legacy
File file = new File("/data/config.json");
// Modern (preferred)
Path path = Path.of("/data/config.json");
Path path2 = Paths.get("/data", "config.json"); // same resultBuffering:
Files.readString() reads the entire file into memory — fine for small files. For large files, use Files.lines() (returns a Stream) or BufferedReader for line-by-line processing without loading everything into memory.
Character encoding:
Always specify charset explicitly. Never use FileReader/FileWriter — they use the platform default charset which varies by OS.
💻 Example
File Operations in Enterprise Java — Common file I/O patterns used in production applications.
🤔 Common Confusions
❓ What is the difference between Path and File?
Path (java.nio.file.Path) is the modern representation of a file system path — use it for all new code. File (java.io.File) is the legacy class from Java 1.0. Path has better exception handling, supports symbolic links, and has a richer API. Convert between them: file.toPath() and path.toFile() when interoperating with legacy APIs.
❓ When should I use Files.readString() vs Files.lines()?
Files.readString() loads the entire file into a String in memory — use for small files (< 10MB). Files.lines() returns a lazy Stream<String> — use for large files where you do not need all lines in memory at once. Always close the stream from Files.lines() with try-with-resources.
🚨 Common Production Issues
File handle leak — not closing streams and readers leads to "too many open files" errors. Always use try-with-resources.
Platform-dependent line endings — files created on Windows have \r\n; Linux has \n. Use Files.readAllLines() which handles both, or normalize with line.stripTrailing().
Charset issues — reading a UTF-8 file without specifying charset may use the platform default (not UTF-8 on some Windows systems). Always specify StandardCharsets.UTF_8.
✅ Best Practices
Use Path.of() and Files utility class for all file operations.
Always specify charset explicitly — StandardCharsets.UTF_8 for most cases.
Always use try-with-resources for streams and readers.
Use Files.lines() for large files — do not load entire large files into memory.
Use atomic file replacement (write to temp, then move) for config files.
Use Files.createTempFile() for temporary files and delete them in finally.
🏛️ Architect's Note
For enterprise file processing (large CSV imports, bulk exports), avoid loading entire files into memory. Use Files.lines() for streaming line-by-line processing, or Apache Commons CSV / OpenCSV for CSV parsing. For Excel files, use Apache POI with streaming API (SXSSFWorkbook). For very large files (GBs), consider Java NIO channels with ByteBuffers for maximum performance.
💬 Frequently Asked Questions
🎯 Key Takeaways
🔗 Related Topics
🎯 Practice this topic in interviews
Core Java Interview Prep
Practice interview questions that connect directly to this technology track.
↗ Where this topic fits
Core Java Technology Guide
Return to the Core Java learning hub.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
Sources
Sources / References
Use these Core Java references to verify the concept in official docs and continue into the most relevant SplashRide pages.
Official documentation
Related SplashRide pages
SplashRide Core Java learning path
Browse the full Core Java topic collection and learning order on SplashRide.
Core Java Interview Prep
Practice Core Java interview questions and scenario-based answers.
Backend Engineer Career Path
A structured journey through Core Java, Spring Boot, production backend engineering, and interview preparation.
Full Stack Java Developer Career Path
A guided route through frontend foundations, Java backend engineering, delivery workflows, and interview readiness.
NIO
Java NIO (New I/O) — Channels, Buffers, Selectors, and when to use NIO over traditional I/O for high-performance network and file operations.
Try Catch
Java exception handling — try-catch-finally, multi-catch, try-with-resources, and the patterns senior developers use to write resilient enterprise code.