Master Java File I/O: Practical Tips for Reading, Writing, and Managing Files
This article explains the fundamentals of Java I/O streams, showing how to efficiently read, write, copy, delete, move, and inspect both text and binary files using NIO, Buffered streams, and modern APIs, while providing ready‑to‑use code examples.
Introduction
Developers should know that a computer has two core capabilities: computation and storage, and storage is essentially I/O (Input/Output). I/O can be divided into file I/O (local program and disk interaction) and network I/O (TCP data transmission).
Java unifies these concepts by treating any data flow as a stream, whether it is a byte stream or a character stream.
1. Essence of Input/Output Streams
Java streams are divided into InputStream/Reader (reading data from the outside) and OutputStream/Writer (writing data to the outside). The external source can be a file, a socket, a multipart upload, or a byte array.
All I/O operations can be summarized in three steps:
Determine the base class (byte vs. character).
Identify the data source or target (File, ByteArray, Socket, etc.).
Choose a decorator class (e.g., BufferedReader, BufferedWriter) to add buffering, formatting, or other features. Remember the rule: first decide byte or character, then the source, then the decorator.
2. Handling Text Files
Text files are readable with a text editor and are processed with character streams. The typical combination is Reader/FileReader → BufferedReader for reading and Writer/FileWriter → BufferedWriter for writing.
String uri = "/Users/Desktop/target.txt";
List<String> lines = Files.readAllLines(Paths.get(uri), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
Files.write(Paths.get(uri), lines, StandardCharsets.UTF_8,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE);Other common operations include copying, deleting, moving, and inspecting file attributes using Files and BasicFileAttributes or PosixFileAttributes for permission details.
Path path = Paths.get("/Users/Desktop/target2.txt");
BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
String perms = getPermissions(path);
String owner = Files.getOwner(path).getName();
long size = attr.size();
String time = DateTimeFormatter.ofPattern("MMM dd HH:mm")
.withZone(ZoneId.systemDefault())
.format(attr.lastModifiedTime().toInstant());
String name = path.getFileName().toString();
System.out.printf("%s %s %8d %s %s%n", perms, owner, size, time, name);3. Handling Binary Files
Binary files (images, videos, archives, etc.) are processed with byte streams. Typical scenarios are uploading/downloading, in‑memory processing, and generating compressed archives.
// Upload example (Spring MVC)
MultipartFile file = null; // actual file from request
Path target = Paths.get("/Users/uploads/" + file.getOriginalFilename());
Files.createDirectories(target.getParent());
try (InputStream in = file.getInputStream()) {
Files.copy(in, target, StandardCopyOption.REPLACE_EXISTING);
}
// Download example (zero‑copy)
HttpServletResponse response = null; // actual response
Path filePath = Paths.get("/Users/uploads/", filename);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(filename, "UTF-8") + "\"");
try (InputStream in = Files.newInputStream(filePath);
OutputStream out = response.getOutputStream()) {
in.transferTo(out);
}In‑memory streams such as ByteArrayOutputStream and ByteArrayInputStream are useful for temporary data that should not touch the disk.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// write data to baos
InputStream in = new ByteArrayInputStream(baos.toByteArray());Examples include creating a ZIP archive in memory, generating an Excel file with EasyExcel, or loading a key file into a byte array.
// ZIP in memory
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
zos.putNextEntry(new ZipEntry("hello.txt"));
zos.write("Hello, this is a file inside the zip!".getBytes("UTF-8"));
zos.closeEntry();
}
InputStream zipIn = new ByteArrayInputStream(baos.toByteArray());4. Decorator Classes – Standard vs. Third‑Party
Java’s standard library provides decorators for common formats (ZIP, images, text, audio). For more complex formats like PDF, Office, or video, third‑party libraries are required (e.g., Apache PDFBox, Apache POI, iText, FFmpeg). File Type Recommended Library Notes PDF Apache PDFBox, iText Read, generate, sign, merge PDFs Word (.doc/.docx) Apache POI (HWPF/XWPF) Read paragraphs, images, tables Excel (.xls/.xlsx) Apache POI (HSSF/XSSF), EasyExcel Large‑scale read/write CSV OpenCSV, SuperCSV Column‑wise processing for huge files JSON Jackson, Gson, Fastjson2 Serialization / deserialization Compression (rar/7z/tar/gz) Apache Commons Compress Universal archive support
5. Conclusion
The purpose of this article is not to make you memorize a list of Java I/O classes, but to give you a holistic view of data flow and storage. Once you grasp that everything is a stream of bytes, you can confidently tackle IM systems, logging, file services, or media processing.
Lin is Dream
Sharing Java developer knowledge, practical articles, and continuous insights into computer engineering.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
