Programación en castellano
-Tutoriales

Programacion en red


Entrada/Salida Parte 2

. Flujos de acceso a archivos

En esta sección vamos a empezar a trabajar con flujos "reales", creados por nosotros mismos. El primero tipo de flujo va a ser FileInputStream. Esta clase, heredera directa de InputStream, es una clase no abstracta, destinada a la lectura de archivos en disco. Posteriormente veremos la clase complementaria, FileOutputStream.

. Utilización de la clase FileInputStream

Para crear un objeto de tipo FileInputStream, necesitamos indicarle al constructor de la clase el nombre del archivo que queremos leer. Esto creará un objeto que, a todos los efectos, se comportará como un objeto de tipo InputStream, es decir, podremos considerarlo como un "tubo" del cual extraemos bytes de uno en uno. No nos importa el hecho de que en el otro extremo del "tubo" haya un archivo del que vienen los datos. Podremos trabajar con el "tubo" usando las técnicas vistas en el caso de InputStream.

La forma más directa de abrir un archivo para leer su contenido es la siguiente. En este ejemplo, abrimos el archivo c:\dir\subdir\archivo y realizamos la suma de sus bytes.

try  
{  
  FileInputStream fis = new FileInputStream("c:\\dir\\subdir\\archivo");  
  int parcial,total=0;  
  while ((parcial=fis.read())!=-1) total += parcial;  
}  
catch(FileNotFoundException fnfe) 
{  
  /* Archivo no encontrado */  
} 
catch (IOException ioe) 
{  
  /* Error al leer */  
}

En este fragmento de código tenemos que comprobar también que no se produzca una excepción porque el archivo no exista. Si no lo comprobáramos, el control pasaría al catch de IOException, que es la clase "madre" de FileNotFoundException. También hay que resaltar las dobles barras hacia atrás, necesarias por la forma que tiene Java de tratar los códigos de escape en las cadenas de texto.

Es importante ver que, aunque el objeto fis sea de tipo FileInputStream, podemos trabajar con él como si fuera un objeto de tipo InputStream, debido a la herencia. Esto es común a casi todos los flujos.

. La clase File

En la sección anterior hemos visto uno de los posibles constructores de la clase FileInputStream: el que recibe como parámetro un nombre de archivo para leer. Existe otras dos variantes: una que recibe un objeto de tipo File y otra que recibe un objeto de tipo FileDescriptor. Veamos en qué consiste la clase File.

La clase File sirve para encapsular la interacción de nuestros programas con el sistema de archivos. Mediante la clase File no nos limitamos a leer el contenido de un archivo, como ocurría con la clase FileInputStream, sino que podemos obtener información adicional, como el tamaño del archivo, su tipo, su fecha de creación, los permisos de acceso que tenemos sobre él, etc.

Además, la clase File es la única forma que tenemos de trabajar con directorios (crearlos, ver los archivos que contienen, cambiar el nombre o borrar los archivos, etc.)

La forma más sencilla de crear un objeto File es:

File miArchivo = new File("c:\\temp\\archivo.txt");

Es muy importante darse cuenta de la diferencia entre un objeto de tipo File y el archivo o directorio al que se refiere. Por ejemplo, el archivo c:\temp\archivo.txt que aparece en el fragmento de código anterior no tiene por qué existir. Para saber si un objeto File se refiere a un archivo existente podemos usar el método exists():

File miArchivo = new File("c:\\temp\\archivo.txt");  
if (miArchivo.exists())  
{  
  /*      El archivo existe       */  
} 
else  
{  
  /*      El archivo no existe    */  
}

Podemos obtener más información de un objeto File:

File f = new File("c:\\temp\\archivo.txt");  
long = f.length();                       /* Tamaño del archivo */  
boolean lectura = f.canRead()    /* ¿Podemos leer el archivo? */  
boolean escritura = f.canWrite() /* ¿Podemos escribir el archivo? */  

if (f.delete())  
   {       /* Archivo borrado con éxito            */      }  
else  
   {       /* El archivo no se ha podido borrar    */      }  

String nombre = f.getName()  /*  Nombre (sin directorio) del archivo */  
String dir = f.getParent()        /* Directorio del archivo */  

if (f.isDirectory())  
   {       /*      Es un directorio                */      }  
else  
   {       /*      No es un directorio             */      }  

if (f.isFile())  
   {       /*      Es un archivo normal            */      }  
else  
   {       /*      No es un archivo normal         */      }  

long modificado = f.lastModified(); /* Fecha de última modificación */  

if (f.renameTo(new File("c:\\temp\\otroArchivo.txt")))  
   {       /*      Nombre de archivo modificado            */      }  
else  
   {       /*      Nombre de archivo no modificado         */      }

Las siguientes líneas de código muestran algunos ejemplo sobre como trabajar con directorios mediante la clase File:

File f = new File("c:\\temp");  
String[] lista = f.list();  /* Obtenemos la lista de archivos */  
for(int n=0;n<lista.length;n++) /* Los imprimimos */  
   System.out.println("Archivo nº " + n + " : " + lista[n]);  

File g = new File("c:\\temp\\dir1");  
if (g.mkdir())  
   {       /* Hemos creado el directorio  
              dir1 en el directorio c:\temp,  
              previamente existente. */       
   } 
else  
   {       /*      No lo hemos podido crear        */      }  

File h = new File("c:\\temp\\dirA\\dirB\\dirC\\dirD");  
if (h.mkdirs())  
   {       /* Hemos creado el directorio dirD,  
              junto con los directorio intermedios  
              necesarios. */       
   }  
else  
   {       /*      No lo hemos podido crear      */      }

. Utilización de la clase FileOutputStream

El próximo paso es el esperado: abrir un archivo y escribir en él. Hay varias formas de realizar esto, todas prácticamente simétricas a las utilizadas para leer archivos. Por ejemplo:

/* Creamos un stream de salida sobre el archivo */  
FileOutputStream fos = new FileOutputStream("c:\\temp\\archivo.dat");  
/* Vamos a escribir los números del 1 al 10 en el archivo  */  
for(int n=0;n<10;n++) 
{  
   fos.write(n);  
}  
fos.close();

Otro ejemplo podría ser el siguiente programa, que pretende ser una versión simplificada del comando copy de MS-DOS:

import java.io.*;  
class copy 
{  
   public static void main(String args[]) 
   {  
      String origen = args[0];  
      String destino = args[1];  
      byte buffer[]= new byte[1024];  
      int cuenta;  
      try 
      {  
         FileInputStream fis = new FileInputStream(origen);  
         FileOutputStream fos = new FileOutputStream(destino);  
         while((cuenta=fis.read(buffer))>0)  
            fos.write(buffer,cuenta);  
      }  
      catch(IOException ioe) 
      {  
         System.err.println("Se ha producido un error");  
         ioe.printStackTrace();  
      }  
   }  
} 

Si ejecutamos este programa mediante

java copy c:\temp\archivo1.txt "c:\mis documentos\archivo2.txt"

el programa copiará el contenido de un archivo en el otro. Si el archivo destino ya existe, será borrado. Si el archivo origen no existe, el catch del programa nos avisará y volcará en pantalla el contenido de la pila de llamadas (aunque en este programa tan simple no sea de ninguna utilidad).

Consultando la documentación del JDK podemos ver que también podemos crear un objeto FileOutputStrem mediante un objeto File. Su utilización sería similar a la que hemos visto antes para FileInputStream.

 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: musica mp3 | logos y melodias | hospedaje web linux | registro de dominios | servidores dedicados
más internet: comprar | recursos gratis | posicionamiento en buscadores | tienda virtual | gifs animados