Introducción al manejo de ficheros

El fichero o archivo es un conjunto de bits almacenado en un dispositivo, es decir, los datos no son volátiles como ocurre con los datos de la memoria RAM. Estos ficheros se ubican en las carpetas o directorios y su nombre será único en dicho directorio. Los ficheros suelen llevar asociada una extensión para saber de que tipo de fichero se trata.

La manera en que se organizan los datos dentro de un fichero depende únicamente del diseñador de ese tipo de archivo.

¿Cuales son algunas de las propiedades de un fichero?

  • Tamaño
  • Nombre
  • Tipo
  • Ruta
  • Extensión

Clases asociadas a las operaciones de gestión de ficheros

Manejo de ficheros en Java.

Un objeto de la clase File

  • representa un fichero, apunta mediante su ruta a un fichero
  • o directorio del sistema de archivos
  • o también se puede crear un nuevo fichero
  • NO representa el contenido de ningún fichero

La clase File, nos va a proporcionar una serie de utilidades, evidentemente dependiendo de la plataforma en la que nos encontremos (Linux, Mac o Windows) cambiarán las rutas de los directorios de los archivos, además en los sistemas Linux y Mac habrá que tener en cuenta que en las rutas se distinguen mayúsculas de minúsculas, cosa que no ocurre en los sistemas Windows.

La clase File, puede representar tanto un fichero concreto o bien un conjunto de ficheros de un directorio. También podemos utilizar la clase para crear nuevos directorios o ficheros.

La clase File, puede utilizar cualquiera de los siguientes constructores:

  1. File(String directorioyfichero)
    1. Linux: new File(“/directorio/subdirectorio/fichero1.txt”);
    2. Windows: new File(“c:\\directorio\\subdirectorio\\fichero1.txt”);
  2. File(String directorio, String fichero)
    1. Linux: new File(“/directorio/subdirectorio”,”fichero1.txt”);
  3. File(File directorio, String fichero)
    1. Linux: new File(new File (“/directorio/subdirectorio”),”fichero1.txt”);

En Java el separador de archivos tanto para Windows como para Linux es el símbolo /, aunque las rutas se escriben en: Linux / y en Windows \\

La clase File tenemos un par de constantes muy útiles, que nos servirán si usamos nuestra aplicación en varios sistemas operativos. Nos permitirá mostrar el separador entre ficheros  entre rutas de cada sistema operativo, por ejemplo, para Windows, se separan las rutas con “;” y los directorios con “\”. y en Unix/Linux se separan con “:” y “/” respectivamente. Los métodos son pathSeparator y separator.

 

String path = File.separator + "var"+ File.separator + "temp"
String listOfFiles = ...
String[] filePaths = listOfFiles.split(File.pathSeparator);

 

Utilizar estas constantes nos evitará duplicar código a la hora de trabajar con ficheros dependiendo si es un sistema Windows o Unix

// tercer constructor
File directorio= new File("/home/juanjo");
File fichero= new File (directorio,"MisDatos.txt");

Revisar los métodos de la clase File

A diferencia de otras clases que manejan ficheros, en la clase File no es necesario controlar excepciones en la mayoría de los métodos. Si hay alguna excepción a manejar lo indicaremos.

Estos son los métodos mas conocidos:

 

Nombre Descripción Parámetros Dato devuelto
exists Indica si existe o no el fichero. Ninguno. boolean
isDirectory Indica si el objeto File es un directorio. Ninguno. boolean
isFile Indica si el objeto File es un fichero. Ninguno. boolean
isHidden Indica si el objeto File esta oculto. Ninguno. boolean
getAbsolutePath Devuelve una cadena con la ruta absoluta del fichero o directorio. Ninguno. String
canRead Indica si se puede leer. Ninguno. boolean
canWrite Indica si se puede escribir. Ninguno. boolean
canExecute Indica si se puede ejecutar. Ninguno. boolean
getName Devuelve una cadena con el nombre del fichero o directorio. Ninguno. String
getParent Devuelve una cadena con el directorio padre. Ninguno. String
listFiles Devuelve un array de File con los directorios hijos. Solo funciona con directorios. Ninguno. Array de File
list Devuelve un array de String con los directorios hijos. Solo funciona con directorios. Ninguno. Array de String
mkdir Permite crear el directorio en la ruta indicada. Solo se creara si no existe. Ninguno. boolean
mkdirs Permite crear el directorio en la ruta indicada, también crea los directorios intermedios. Solo se creara si no existe. Ninguno. boolean
createNewFile Permite crear el fichero en la ruta indicada. Solo se creara si no existe. Debemos controlar la excepcion con IOException. Ninguno. boolean

 

import java.io.File;
import java.io.IOException;
public class EjemploFileApp {
 
    public static void main(String[] args) throws IOException {
 
        //Creamos objetos File
        File fichero=new File("F:\\fich_binario.ddr");
        File fichero2=new File("F:\\fichero.txt");
        File directorio=new File("F:\\prueba");
        File directorio2=new File("F:\\directorio");
 
        //Creo los ficheros y directorios
        fichero.createNewFile();
        fichero2.createNewFile();
        directorio.mkdir();
        directorio2.mkdir();
         
        //Indica si existen los archivos
        System.out.println("Existencia: ");
        System.out.println("Fichero "+fichero.exists());
        System.out.println("Directorio "+directorio.exists());
 
        System.out.println("");
 
        //Indica si son directorios
        System.out.println("¿Son directorios?: ");
        System.out.println("Fichero "+fichero.isDirectory());
        System.out.println("Directorio "+directorio.isDirectory());
 
        System.out.println("");
 
        //Indica si son ficheros
        System.out.println("¿Son ficheros?: ");
        System.out.println("Fichero "+fichero.isFile());
        System.out.println("Directorio "+directorio.isFile());
 
        System.out.println("");
 
        //Indica la ruta absoluta del fichero o directorio
        System.out.println("Ruta absoluta: ");
        System.out.println("Fichero "+fichero.getAbsolutePath());
        System.out.println("Directorio "+directorio.getAbsolutePath());
 
        System.out.println("");
 
        //Indica si se puede leer
        System.out.println("¿Se pueden leer?:");
        System.out.println("Fichero "+fichero.canRead());
        System.out.println("Directorio "+directorio.canRead());
 
        System.out.println("");
 
        //Indica si se puede escribir
        System.out.println("¿Se pueden escribir?:");
        System.out.println("Fichero "+fichero.canWrite());
        System.out.println("Directorio "+directorio.canWrite());
 
        System.out.println("");
 
        //Indica si se puede ejecutar
        System.out.println("¿Se pueden ejecutar?:");
        System.out.println("Fichero "+fichero.canExecute());
        System.out.println("Directorio "+directorio.canExecute());
 
        System.out.println("");
 
        //Indica el nombre sin rutas
        System.out.println("Nombres sin rutas: ");
        System.out.println("Fichero "+fichero.getName());
        System.out.println("Directorio "+directorio.getName());
 
        System.out.println("");
 
        //Indica el nombre del directorio padre
        System.out.println("Nombre del directorio padre: ");
        System.out.println("Fichero "+fichero.getParent());
        System.out.println("Directorio "+directorio.getParent());
 
        System.out.println("");
 
        //Guarda en un array de File los directorios hijos, solo con directorios
        System.out.println("Nombre de los objetos File dentro de un array");
        File lista[]=directorio.listFiles();
        for(int i=0;i<lista.length;i++){
            System.out.println(lista[i]);
        }
 
        System.out.println("");
 
        //Guarda en un array de String los directorios hijos, solo con directorios
        System.out.println("Nombre de los objetos String dentro de un array");
        String listaString[]=directorio.list();
        for(int i=0;i<listaString.length;i++){
            System.out.println(listaString[i]);
        }
 
        System.out.println("");   
    }
}

 

Existencia: 
Fichero true
Directorio true

¿Son directorios?: 
Fichero false
Directorio true

¿Son ficheros?: 
Fichero true
Directorio false

Ruta absoluta: 
Fichero F:\fich_binario.ddr
Directorio F:\prueba

¿Se pueden leer?:
Fichero true
Directorio true

¿Se pueden escribir?:
Fichero true
Directorio true

¿Se pueden ejecutar?:
Fichero true
Directorio true

Nombres sin rutas: 
Fichero fich_binario.ddr
Directorio prueba

Nombre del directorio padre: 
Fichero F:\
Directorio F:\

Nombre de los objetos File dentro de un array

Nombre de los objetos String dentro de un array

Resultado en el disco F:

Si colocamos un fichero y un directorio dentro de la carpeta “prueba” obtendremos el siguiente resultado:

...
Nombre de los objetos File dentro de un array
F:\prueba\CarpetaJJ
F:\prueba\Fichero.txt

Nombre de los objetos String dentro de un array
CarpetaJJ
Fichero.txt

Saber nuestro directorio actual:

...
String dirActual = System.getProperty("user.dir");
...

 

Contar las líneas de un fichero:

public static int CuentaLineas (String filename) throws IOException {
LineNumberReader MiFichero= new LineNumberReader(new FileReader(filename));
while (MiFichero.readLine() != null) {}
MiFichero.close();
return MiFichero.getLineNumber();
}
public class MiClaseContadora{
  private int cuentaLinea;
  private String ficheroTexto = "Hola.txt";
  public static void main(String[] args) throws IOException {
    cuentaLinea = LineCounter.countLines(ficheroTexto);
  }
}
public class ContadorLineas{
  private int cuantaLineas;
  private String ficheroTexto= "Hola.txt";
  public static void main(String[] args) throws IOException {
    try {
      cuantaLineas = LineCounter.countLines(ficheroTexto);
     } catch (IOException e) {
       throw new IllegalArgumentException("No podemos abrir " + ficheroTexto, e);
     }
  }
}

Ejercicios

  1. Crea un programa que muestre el contenido de un directorio y liste todos los nombres de archivos o directorios. Luego mejoralo para que liste la información al estilo linux. Por último en caso que algún archivo tenga la extensión “.txt” tendrá que indicar el número de filas que tiene el archivo.
  2. Crea un programa que muestre las diferencias entre getPath(), getAbsolutePath() y getCanonicalPath().

 

Ruta Path Absoluta Canónica
C:\temp\fichero.txt
.\fichero.txt No No
C:\temp\aaa\bbb\..\\..\fichero.txt No

 

Ejemplo que lista una ruta que se le pasa como argumento:

package damdaw;

import java.io.File;
import java.io.IOException;

public class ListadoDirectorio {
  public static void main(String[] args) throws IOException {
    String ruta=".";
    if (args.length>=1) ruta = args[0];
    File fich = new File(ruta);
    if(!fich.exists()) {
      System.out.println("No exite "+ruta);
    } else {
      if(fich.isFile()) {
        System.out.println(ruta+" es un fichero");
      } else {
        System.out.println(ruta+" es un directorio");
        File[] ficheros=fich.listFiles();
        for (File f:ficheros) {
          String textoDescr = f.isDirectory() ? "/" :
            f.isFile() ? "_" : "?";
          System.out.println("("+textoDescr+") "+f.getName());
          
        }
      }
    }
    }
  }

 

Actividades

  1. ACT01: Crea un programa que muestre por pantalla el listado de ficheros y directorios a partir del directorio que le pasemos por la entrada estándar, de la siguiente forma:
    Si es directorio pondremos d-NOMDIR y cuando sea archivo normal f-NOMFICH. Indicar si el fichero es de lectura o escritura mediante (L/E). Si el directorio que le pasamos no existe se tendrá que indicar con un mensaje de error.
  2. ACT02: Crea un programa que muestra el contenido de un directorio que le pasemos por parámetro en la consola de comandos que indique el nombre del directorio pasado y liste todos sus subdirectorios de forma recursiva. Para cada directorio se muestran primero los archivos y a continuación las carpetas que contienen de forma recursiva. Tanto el Linux como Windows existe el comando “tree”, intenta realizar un programa recursivo en Java llamado “arbol” que haga lo mismo que ese comando.
  3. Pista

     
     
    import java.io.File;
    import java.io.IOException;
    
    public class TreeCommand {
        public static void printFile(File f, String spaces) {
            System.out.println(spaces.concat(File.separator).concat(f.getName()));
            if (f.isDirectory() && f.canRead()) {
                for (File file : f.listFiles()) {
                    printFile(file, spaces.concat(" "));
                }
            }
     
        }
     
        public static void main(String[] args) throws IOException {
            printFile(new File("/Users/raidentrance/Documents/Github"), "");
        }
    }

    [plegar]
public static final String ANSI_BLACK = "\u001B[30m";
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_GREEN = "\u001B[32m";
public static final String ANSI_YELLOW = "\u001B[33m";
public static final String ANSI_BLUE = "\u001B[34m";
public static final String ANSI_PURPLE = "\u001B[35m";
public static final String ANSI_CYAN = "\u001B[36m";
public static final String ANSI_WHITE = "\u001B[37m";
public static final String ANSI_RESET = "\u001B[0m";

Ejemplo:

System.out.println(ANSI_RED + "Texto de color rojo" + ANSI_RESET);