1. Clase File: cómo empezó todo
Aunque ya hemos visto que es mejor no utilizar la clase File en proyectos nuevos, existen multitud de sistemas heredados (legacy) donde se usa. Por eso es importante comprenderla y saber trabajar con ella. La clase File es la forma antigua de representar un archivo o un directorio en el disco. Pero no te confundas: un objeto File no es el archivo en sí, sino una «referencia»/«descriptor» de la ruta. Por ejemplo, la expresión File f = new File("hello.txt"); no crea un archivo en el disco: solo has descrito la ruta.
¿Cómo crear un objeto File?
import java.io.File;
public class FileDemo {
public static void main(String[] args) {
File file = new File("example.txt"); // ruta relativa
File folder = new File("mydir"); // directorio
System.out.println("Ruta absoluta: " + file.getAbsolutePath());
System.out.println("¿Existe el archivo? " + file.exists());
System.out.println("¿Es un archivo? " + file.isFile());
System.out.println("¿Es un directorio? " + folder.isDirectory());
}
}
Qué es importante recordar:
Crear un objeto File no crea el archivo en el disco. Es solo un «acceso directo». Para que el archivo exista realmente, hay que iniciar su creación explícitamente (por ejemplo, escribir datos o llamar a file.createNewFile()).
Métodos principales de la clase File
- exists() — comprueba si existe el archivo/directorio.
- isFile() — ¿es un archivo (y no una carpeta)?
- isDirectory() — ¿es un directorio?
- getAbsolutePath() — obtener la ruta absoluta.
- length() — tamaño del archivo en bytes.
- getName() — nombre del archivo o carpeta.
- delete() — eliminar archivo/directorio (si está vacío).
Ejemplo: mostramos información sobre el archivo
File file = new File("example.txt");
System.out.println("Nombre: " + file.getName());
System.out.println("Ruta: " + file.getAbsolutePath());
System.out.println("Tamaño: " + file.length() + " bytes");
System.out.println("¿Existe? " + file.exists());
2. Clase Path: una visión moderna de los archivos
Path forma parte del nuevo API de archivos (NIO.2, desde Java 7). Es una abstracción de la ruta a un archivo/directorio; además, la ruta puede estar no solo en el disco local, sino también, por ejemplo, dentro de un archivo ZIP o en un recurso remoto (si existe el proveedor correspondiente).
Si File es un mapa de papel antiguo, Path es un navegador GPS.
¿Cómo crear un objeto Path?
import java.nio.file.Path;
import java.nio.file.Paths;
public class PathDemo {
public static void main(String[] args) {
Path path1 = Paths.get("example.txt"); // ruta relativa
Path path2 = Paths.get("folder", "file.txt"); // unimos las partes de la ruta
System.out.println("Ruta 1: " + path1.toAbsolutePath());
System.out.println("Ruta 2: " + path2.toAbsolutePath());
}
}
Ventaja: no hay que pensar en los separadores. Paths.get elegirá el formato correcto para tu SO.
Conversión entre File y Path
- File → Path: file.toPath()
- Path → File: path.toFile()
File file = new File("test.txt");
Path path = file.toPath();
Path anotherPath = Paths.get("data.txt");
File anotherFile = anotherPath.toFile();
Trabajo con rutas: resolve, relativize, normalize
Unir rutas (resolve)
Path dir = Paths.get("myfolder");
Path file = dir.resolve("notes.txt"); // myfolder/notes.txt
System.out.println(file); // myfolder/notes.txt
Ruta relativa (relativize)
Path pathA = Paths.get("folderA/file1.txt");
Path pathB = Paths.get("folderA/subfolder/file2.txt");
Path relative = pathA.relativize(pathB);
System.out.println(relative); // ../subfolder/file2.txt
Normalización de la ruta (normalize)
Path messy = Paths.get("folder/../folder/file.txt");
Path clean = messy.normalize();
System.out.println(clean); // folder/file.txt
Ejemplo: construimos la ruta a un archivo
Path home = Paths.get(System.getProperty("user.home"));
Path docs = home.resolve("Documents");
Path myFile = docs.resolve("myfile.txt");
System.out.println("Ruta al archivo: " + myFile.toAbsolutePath());
3. Clase Files: tu navaja suiza
La clase Files del paquete java.nio.file es un conjunto utilitario de métodos estáticos para trabajar con archivos y directorios sobre Path. Puede prácticamente todo: comprobar la existencia, crear/eliminar, leer/escribir, copiar/mover, obtener atributos y recorrer el árbol de directorios.
Métodos principales de la clase Files
- Files.exists(path) — comprueba si existe el archivo/directorio.
- Files.isDirectory(path) — ¿es un directorio?
- Files.size(path) — tamaño del archivo.
- Files.createFile(path) — crear un archivo.
- Files.createDirectory(path) — crear un directorio.
- Files.delete(path) — eliminar archivo/directorio.
- Files.copy(src, dest) — copiar un archivo.
- Files.move(src, dest) — mover/renombrar.
- Files.getLastModifiedTime(path) — hora de la última modificación.
- Files.readAllBytes(path) — leer todo el archivo en un array de bytes.
- Files.readAllLines(path) — leer todas las líneas de un archivo de texto.
- Files.write(path, bytes) — escribir bytes en un archivo.
Ejemplo: comprobamos un archivo
import java.nio.file.*;
public class FilesDemo {
public static void main(String[] args) {
Path path = Paths.get("example.txt");
System.out.println("¿Existe el archivo? " + Files.exists(path));
System.out.println("¿Es un directorio? " + Files.isDirectory(path));
if (Files.exists(path)) {
try {
System.out.println("Tamaño del archivo: " + Files.size(path) + " bytes");
} catch (Exception e) {
System.out.println("Error al obtener el tamaño: " + e.getMessage());
}
}
}
}
4. Práctica: creamos objetos y mostramos propiedades
Creamos objetos para un archivo y un directorio
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
public class CompareDemo {
public static void main(String[] args) {
// Forma antigua
File oldFile = new File("test.txt");
File oldDir = new File("mydir");
// Forma nueva
Path newFile = Paths.get("test.txt");
Path newDir = Paths.get("mydir");
System.out.println("=== File API ===");
System.out.println("Archivo: " + oldFile.getAbsolutePath());
System.out.println("¿Existe? " + oldFile.exists());
System.out.println("¿Es un archivo? " + oldFile.isFile());
System.out.println("¿Es un directorio? " + oldDir.isDirectory());
System.out.println("\n=== Path API ===");
System.out.println("Archivo: " + newFile.toAbsolutePath());
System.out.println("¿Existe? " + java.nio.file.Files.exists(newFile));
System.out.println("¿Es un archivo? " + java.nio.file.Files.isRegularFile(newFile));
System.out.println("¿Es un directorio? " + java.nio.file.Files.isDirectory(newDir));
}
}
Mostramos las propiedades del archivo
import java.nio.file.*;
public class FileProperties {
public static void main(String[] args) {
Path path = Paths.get("test.txt");
System.out.println("Ruta absoluta: " + path.toAbsolutePath());
System.out.println("Nombre de archivo: " + path.getFileName());
System.out.println("Carpeta padre: " + path.getParent());
if (Files.exists(path)) {
try {
System.out.println("Tamaño: " + Files.size(path) + " bytes");
System.out.println("Última modificación: " + Files.getLastModifiedTime(path));
} catch (Exception e) {
System.out.println("Error al obtener la información: " + e.getMessage());
}
} else {
System.out.println("Archivo no encontrado.");
}
}
}
5. Comparación: File vs Path/Files
| Capacidad | File (java.io) | Path + Files (java.nio.file) |
|---|---|---|
| Representación de la ruta | Solo disco local | Disco local, ZIP, recursos de red |
| Unión de rutas | Unión manual con barras | Cómodo mediante resolve |
| Comprobación de existencia | exists() | Files.exists(path) |
| Lectura/escritura de contenido | No | Sí (Files.readAll..., Files.write) |
| Obtención de atributos | Básicos (length(), lastModified()) | Atributos ampliados y vistas |
| Compatibilidad | Con todas las versiones de Java | Java 7 y superiores |
| Trabajo con enlaces simbólicos | Limitado | Compatibilidad completa |
En breve: ¿cuándo usar cada uno?
- Para proyectos nuevos — utiliza Path y Files.
- Para mantener código antiguo — a veces habrá que trabajar con File.
6. Matices útiles
Rutas relativas y absolutas
Una ruta relativa es una ruta respecto al directorio de trabajo actual; una absoluta es la ruta completa desde la raíz del sistema de archivos.
Path relative = Paths.get("data", "file.txt");
Path absolute = relative.toAbsolutePath();
System.out.println("Ruta absoluta: " + absolute);
Multiplataforma
Path y Files tienen en cuenta las particularidades del SO (separadores, codificaciones, etc.). No escribas rutas manualmente del tipo "C:\\folder\\file.txt"; usa Paths.get y resolve.
Conversión entre File y Path
Si tienes código antiguo con File, es fácil pasar al nuevo API:
File legacy = new File("legacy.txt");
Path modern = legacy.toPath();
if (Files.exists(modern)) {
// Ahora se pueden usar todas las posibilidades de NIO.2
}
Comprobar la existencia de un archivo
Path path = Paths.get("notes.txt");
if (Files.exists(path)) {
System.out.println("¡Archivo encontrado!");
} else {
System.out.println("El archivo no existe.");
}
7. Mini práctica: creamos y comprobamos un archivo y un directorio
import java.nio.file.*;
public class MiniPractice {
public static void main(String[] args) throws Exception {
Path dir = Paths.get("demo_dir");
Path file = dir.resolve("hello.txt");
// Creamos el directorio si no existe
if (!Files.exists(dir)) {
Files.createDirectory(dir);
System.out.println("Directorio creado: " + dir.toAbsolutePath());
}
// Creamos el archivo si no existe
if (!Files.exists(file)) {
Files.createFile(file);
System.out.println("Archivo creado: " + file.toAbsolutePath());
}
// Mostramos las propiedades
System.out.println("¿Existe el archivo? " + Files.exists(file));
System.out.println("¿Es un archivo? " + Files.isRegularFile(file));
System.out.println("Tamaño: " + Files.size(file) + " bytes");
// Eliminamos el archivo y el directorio (opcional)
Files.delete(file);
Files.delete(dir);
System.out.println("Archivo y directorio eliminados.");
}
}
8. Errores típicos al trabajar con File/Path/Files
Error n.º 1: confundir File y Path. Muchos principiantes intentan usar métodos de Files con un objeto File. Recuerda: Files.* funciona con Path. Si tienes un File, primero haz file.toPath().
Error n.º 2: esperar que crear un objeto File o Path cree el archivo. Un objeto de ruta es un acceso directo, no un archivo real. Para crearlo usa Files.createFile(path) o la escritura de datos.
Error n.º 3: construir rutas manualmente concatenando cadenas. No escribas "folder/file.txt" ni "folder\\file.txt". Usa Paths.get(...) y resolve(...). Es más seguro y multiplataforma.
Error n.º 4: ignorar excepciones. Las operaciones con archivos lanzan IOException y otras excepciones. Manéjalas con try-catch o propágalas (throws).
Error n.º 5: comprobar con File.exists() y luego trabajar con Path. Procura mantener un solo estilo: si empiezas con Path, usa Files.exists(path) y el resto de métodos de Files.
GO TO FULL VERSION