🏷 I/O
10 patterns
Topic: I/O
All Java patterns related to I/O — java.evolved
I/O
Deserialization filters
Old
// Dangerous: accepts any class
ObjectInputStream ois =
new ObjectInputStream(input);
Object obj = ois.readObject();
// deserialization attacks possible!
Modern
ObjectInputFilter filter =
ObjectInputFilter.Config
.createFilter(
"com.myapp.*;!*"
);
ois.setObjectInputFilter(filter);
Object obj = ois.readObject();
hover to see modern →
JDK 9+
learn more →
I/O
File memory mapping
Old
try (FileChannel channel =
FileChannel.open(path,
StandardOpenOption.READ,
StandardOpenOption.WRITE)) {
MappedByteBuffer buffer =
channel.map(
FileChannel.MapMode.READ_WRITE,
0, (int) channel.size());
// Limited to 2GB
// Freed by GC, no control
}
Modern
FileChannel channel =
FileChannel.open(path,
StandardOpenOption.READ,
StandardOpenOption.WRITE);
try (Arena arena = Arena.ofShared()) {
MemorySegment segment =
channel.map(
FileChannel.MapMode.READ_WRITE,
0, channel.size(), arena);
// No size limit
// ...
} // Deterministic cleanup
hover to see modern →
JDK 22+
learn more →
I/O
Files.mismatch()
Old
// Compare two files byte by byte
byte[] f1 = Files.readAllBytes(path1);
byte[] f2 = Files.readAllBytes(path2);
boolean equal = Arrays.equals(f1, f2);
// loads both files entirely into memory
Modern
long pos = Files.mismatch(path1, path2);
// -1 if identical
// otherwise: position of first difference
hover to see modern →
JDK 12+
learn more →
I/O
Modern HTTP client
Old
URL url = new URL("https://api.com/data");
HttpURLConnection con =
(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
// read lines, close streams...
Modern
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create("https://api.com/data"))
.build();
var response = client.send(
request, BodyHandlers.ofString());
String body = response.body();
hover to see modern →
JDK 11+
learn more →
I/O
InputStream.transferTo()
Old
byte[] buf = new byte[8192];
int n;
while ((n = input.read(buf)) != -1) {
output.write(buf, 0, n);
}
Modern
input.transferTo(output);
hover to see modern →
JDK 9+
learn more →
I/O
IO class for console I/O
Old
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
System.out.print("Name: ");
String name = sc.nextLine();
System.out.println("Hello, " + name);
sc.close();
Modern
String name = IO.readln("Name: ");
IO.println("Hello, " + name);
hover to see modern →
JDK 25+
learn more →
I/O
Path.of() factory
Old
Path path = Paths.get("src", "main",
"java", "App.java");
Modern
var path = Path.of("src", "main",
"java", "App.java");
hover to see modern →
JDK 11+
learn more →
I/O
Reading files
Old
StringBuilder sb = new StringBuilder();
try (BufferedReader br =
new BufferedReader(
new FileReader("data.txt"))) {
String line;
while ((line = br.readLine()) != null)
sb.append(line).append("\n");
}
String content = sb.toString();
Modern
String content =
Files.readString(Path.of("data.txt"));
hover to see modern →
JDK 11+
learn more →
I/O
Try-with-resources improvement
Old
Connection conn = getConnection();
// Must re-declare in try
try (Connection c = conn) {
use(c);
}
Modern
Connection conn = getConnection();
// Use existing variable directly
try (conn) {
use(conn);
}
hover to see modern →
JDK 9+
learn more →
I/O
Writing files
Old
try (FileWriter fw =
new FileWriter("out.txt");
BufferedWriter bw =
new BufferedWriter(fw)) {
bw.write(content);
}
Modern
Files.writeString(
Path.of("out.txt"),
content
);
hover to see modern →
JDK 11+
learn more →