The I/O Universe: Bytes vs Characters
On disk everything is binary. The distinction lies in whether the JVM reads raw 8-bit bytes or decodes them into 16-bit Unicode characters via a Charset.
Handles raw 8-bit bytes. Best for PNG images, audio, PDFs, and binary blobs.
Decodes bytes into Unicode text (16-bit char) applying a Charset (UTF-8, ISO-8859-1).
The Decorator Pattern: The Stream Onion
Instead of class explosion, java.io stacks concentric wrappers over physical sources: RAM buffering and typed parsing.
The buffer loads 8192 bytes into RAM in one OS kernel call. The next 8191 reads execute in memory.
Modern Java NIO.2: java.nio.file
Java 7 replaced the fragile java.io.File with immutable Path, atomic Files operations, and lazy streams via Files.walk().
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
String linea;
while ((linea = br.readLine()) != null) {
System.out.println(linea);
}
} finally {
if (br != null) br.close();
} Path path = Paths.get("file.txt");
// Lectura directa en 1 línea
List<String> lineas = Files.readAllLines(path, StandardCharsets.UTF_8);
// O Lazy Stream para archivos gigantes (GBytes):
try (Stream<Path> stream = Files.walk(path)) {
stream.filter(Files::isRegularFile).forEach(System.out::println);
} Serialization: Flattening the Heap to Disk
ObjectOutputStream converts live object graphs into a binary sequence prefixed with the signature 0xAC ED 00 05.
The Critical Role of serialVersionUID
If a class changes without a declared serialVersionUID, JVM computes a dynamic hash and deserialization fails with InvalidClassException.
Guardamos Factura(id, monto). Hash dinámico calculado: 0x84A1
Agregamos emailCliente al código fuente. Nuevo hash: 0x32B9
❌ InvalidClassException: local class incompatible (stream: 0x84A1, local: 0x32B9)
// Declarar siempre un identificador de versión explícito:
private static final long serialVersionUID = 1L; Anatomy of a JAR (Java Archive)
A .jar file is not magic: it is a standard ZIP compressed archive holding compiled bytecode and a MANIFEST.MF descriptor.
- 📁 META-INF/
- 📄 MANIFEST.MF
- 📁 com/empresa/app/
- 📄 Main.class
- 📄 Servicio.class
- 📄 Modelo.class
- 📁 resources/
- 🖼️ logo.png
Manifest-Version: 1.0
Main-Class: com.empresa.app.Main
Created-By: 21.0.2 (Eclipse Adoptium) $ java -jar mi-aplicacion.jar The JVM opens the ZIP, reads Main-Class from MANIFEST.MF, and launches public static void main(String[] args).
Native Distribution with jpackage
The era of asking users to "Install Java first" is over. jpackage builds native installers (.exe, .dmg, .deb) bundled with a custom JRE.
Genera archivos de bytecode .class.
Genera el archivo ejecutable .jar con su manifiesto.
Corta un JRE mínimo (30 MB en vez de 300 MB del JDK).
Produce instaladores .exe, .dmg o .deb 100% autónomos.