Sie sind auf Seite 1von 58

Tema 8.

Ficheros y Excepciones
Programacin
Curso 2014/15
Departamento de Sistemas Informticos y Computacin

Programacin 2014/15 - Tema 8

Resultados de aprendizaje

Saber gestionar (leer y escribir) ficheros de texto y binarios en programas.

Saber resolver el tratamiento de excepciones (predefinidas) en el uso de


ficheros en los programas.

Saber crear y utilizar excepciones sencillas en el desarrollo de programas en


Java.

Programacin 2014/15 - Tema 8

Contenido
1.

Introduccin
Excepciones
Flujos y ficheros

2.

Ficheros de texto

3.

Ficheros binarios

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
o

Excepcin: situacin anmala ocurrida durante la ejecucin de un programa.


Divisin entre cero.
Acceso a una posicin inexistente de un vector.
Abrir un fichero inexistente.

Java dispone de mecanismos para:


Detectar excepciones y, en la medida de lo posible, recuperarse de los errores.
Generar excepciones para sealar una situacin anmala en el propio programa
(No sern vistas en la asignatura).

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
Las excepciones pueden ser capturadas. De este modo se tiene conocimiento del error
ocurrido y se puede reaccionar.

try {
// Cdigo susceptible de generar excepciones
} catch (Tipo_Excepcion_A_Capturar

excep) {

// Cdigo para tratar el error


}
// Continua el programa ...

Si se produce una excepcin en el bloque try, se salta al bloque catch y el programa


continua. Si no se produce un error, el bloque catch no se ejecuta.

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
Las excepciones pueden ser capturadas. De este modo se tiene conocimiento del error
ocurrido y se puede reaccionar.

try {
// Cdigo susceptible de generar excepciones
} catch { Tipo_Excepcion_A_Capturar

excep ) {

// Cdigo para tratar el error


}
// Continua el programa ...

Si se produce una excepcin en el bloque try, se salta al bloque catch y el programa


continua. Si no se produce un error, el bloque catch no se ejecuta.

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
Ejemplo de escritura fuera del rango de un vector.
public class EjemploExcepcion {
public static void main (String [] args) {
try {
int [] vec = new int[2] ;
vec [0] = 1 ;
vec [1] = 1 ;
// escribimos fuera del vector
vec [2] = 1 ;
} catch (ArrayIndexOutOfBoundsException e) {
System.err.println ("Error: " + e) ;
}
}
}

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
Ejemplo de divisin entre cero.
public class Exc2 {
public static void main (String args[]) {
int d, a;
try { // controla un bloque de cdigo.
d = 0 ;
a = 42 / d ;
System.out.println ("Esto no se imprimir.") ;
}
catch (ArithmeticException e) { // captura el error de divisin
System.out.println ("Divisin entre cero.") ;
}
System.out.println ("Despus de la sentencia catch.") ;
}
}

Programacin 2014/15 - Tema 8

1. Introduccin: Excepciones
Programa que recibe como parmetro (en la lista de parmetros de main) un nombre y muestra
por pantalla el texto Hola nombre-de-la-persona" o el texto Hola, quien seas..."
en caso de que se produzca una excepcin por el hecho de no haber pasado ningn parmetro
a main.
import java.util.Scanner ;
public class P01_Ejemplo_Excepcion {
public static void main (String [ ] args) {
try {
System.out.print ("Hola " + args[0]) ;
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println ("Hola , quien seas...") ;
}
}
}

Programacin 2014/15 - Tema 8

10

1. Introduccin: Excepciones
Al ordenar los bloques catch, las subclases de excepcin deben ir antes que la superclase
(en caso contrario no se ejecutarn nunca y dar error de compilacin por cdigo no alcanzable,
ya que la 2 excepcin est capturada por la 1).
public class SuperSubCatch {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
}
catch (Exception e) {
System.out.println("catch para cualquier tipo de excepcin.");
}
/* Este catch nunca se ejecutar */
catch (ArithmeticException e) { // ERROR - no alcanzable
System.out.println("Esto nunca se ejecutar.");
}
}
}

Programacin 2014/15 - Tema 8

11

1. Introduccin: Excepciones
Controlar que el valor ledo es un entero.

import java.io.* ;
import java.util.* ;
public class controlErrores {
public static void main (String[] args) {
int valor = leer() ;
System.out.println ("El nmero entero ledo es " + valor) ;
}

Programacin 2014/15 - Tema 8

12

1. Introduccin: Excepciones
Controlar que el valor ledo es un entero.
public static int leer() {
Scanner teclado = new Scanner (System.in) ;
boolean salir = false ;
int leido = 0 ;
do {
try {
System.out.print ("Introduce un entero positivo: ") ;
leido = teclado.nextInt() ;
if (leido < 0)
System.out.println("Error. No es positivo") ;
else
salir = true ;
} catch (InputMismatchException ex) {
System.out.println ("Error. No es un entero") ;
}
String basura = teclado.nextLine() ;
} while (!salir) ;
return leido ;
}
}

13

Programacin 2014/15 - Tema 8

1. Introduccin: ficheros
En Java la entrada/salida se realiza utilizando flujos (streams), que son secuencias de
informacin que tienen una fuente (flujos de entrada) o un destino (flujos de salida).

Fuente

flujo de
entrada
Programa

flujo de
salida

Destino

Programacin 2014/15 - Tema 8

14

1. Introduccin: ficheros
o Un fichero es un conjunto de bits guardado en un dispositivo de almacenamiento
secundario (disco duro, USB stick, etc.).
o Permite almacenar los datos existentes en memoria de un programa para ser utilizados
posteriormente (por ese u otro programa).
o Caractersticas principales:
o

Nombre (i.e. fichero.txt).

Ruta en el dispositivo de almacenamiento (i.e. /home/lucas/docs/file.txt).

Tamao, tipicamente expresado en bytes (Kb, Mbytes, Gbytes, etc.).

o Caractersticas adicionales:
o

Permisos de acceso (dependientes del sistema de archivos).

Fecha de ltima modificacin.

o Acciones principales sobre ficheros:


o

Abrir, Leer, Cerrar.

Abrir, Escribir, Cerrar.

Programacin 2014/15 - Tema 8

15

Tipos de ficheros
En general, distinguimos entre dos tipos de ficheros:

Ficheros de Texto

Escritura/lectura menos eficiente que los


ficheros binarios.

Ej. Un entero de 10 dgitos en un


fichero de texto ocupara 10 bytes

Ficheros Binarios

Almacenamiento eficiente de la informacin.

No interpretable por un ser humano.

Escritura/lectura eficiente.

(asumiendo codificacin ASCII de 1


byte/carcter).

Requiere ms tamao que un fichero binario


para representar la misma informacin.

Generalmente portable (legible en diferentes


equipos).

Interpretable por un ser humano.

Secuencia de caracteres.

Ej. Un entero de 10 dgitos en un fichero


binario ocupa 4 bytes.

Secuencia de bytes interpretables como valores


(primitivos u objetos).

Generalmente no portable (debe ser ledo en el


mismo tipo de ordenador y con el mismo lenguaje
de programacin que fue escrito).

Programacin 2014/15 - Tema 8

16

La clase File
o La clase java.io.File permite abstraer el concepto de fichero y directorio.
o Ofrece mtodos para interaccionar con el sistema de archivos mediante los que se pueden
obtener las principales propiedades de un fichero o directorio: nombre, ruta, si es modificable
o no, ...
o La creacin de un objeto File no implica la construccin de un fichero en el sistema de
archivos.
o Los principales mtodos y constructores disponibles en la clase File son:
public File (String pathname)

Crea un nuevo File a partir de la ruta

public boolean delete ()

Intenta eliminar el fichero. Devuelve true en caso de


xito.

public boolean renameTo (File destino)

Renombra el fichero al nuevo nombre. Devuelve


true en caso de xito.

public boolean exist ()

Devuelve true si el fichero existe

Programacin 2014/15 - Tema 8

17

La clase File
import java.io.* ;
public class ManejoFile {
public static void main (String [] args) {
File f = new File ("/programas/file2.txt") ;
if (f.exists())
System.out.println("El fichero existe") ;
else
System.err.println ("El fichero NO existe") ;
System.out.println ("getName((): " + f.getName()) ;
System.out.println ("getParen(): " + f.getParent()) ;
System.out.println ("length(): " + f.length()) ;
}
}

Programacin 2014/15 - Tema 8

18

2. Ficheros de texto: escritura


La forma ms cmoda de generar y leer ficheros de texto es mediante las clases
PrintWriter y Scanner.
La clase java.io.PrintWriter: Escribe representaciones formateadas de tipos
primitivos a un fichero de tipo texto
Mtodo / Constructor
PrintWriter (File file)
Mtodo / Constructor

Descripcin
Crea un nuevo PrintWriter a partir de un objeto de tipo File. Lanza la
excepcin FileNotFoundException si no se puede escribir en el
Descripcin
fichero

PrintWriter
(OutputStream
out) Crea
PrintWriter(File
file)
Creaununnuevo
nuevoPrintWriter
PrintWriter a partir
de un
a partir
de File
un flujo de salida
void
print (float f) out)
PrintWriter(OutputStream

Crea un
PrintWriter
a partir
de un stream
Escribe
unnuevo
float
(y no termina
la lnea)

void
f)
voidprintln
print(float(float
f)

Escribeununfloat
float (y(ynoaade
termina
la lnea)
Escribe
un salto
de lnea)

void
(boolean
b)
voidprint
println(float
f)

Escribeununboolean
float (y aade
salto de
Escribe
(y noun
termina
la lnea)

void print(boolean b)

print (arg)
void

Escribe un boolean (y no termina la lnea)


un determinado argumento arg en el flujo de salida y no termina la
Escribe

boolean checkError()
void println (arg)

lnea. El argumento puede ser cualquier tipo primitivo o un String.


Comprueba si ha habido error en la escritura anterior
Igual que el anterior, terminando la lnea.

void printf (String sf, args)

Escribe los argumentos args siguiendo la descripcin de formato en sf.

boolean checkError ()

Comprueba si ha habido error en la escritura anterior. Si lo ha habido,


devuelve true.

Programacin 2014/15 - Tema 8

19

La clase PrintWriter
Ejemplos alternativos de creacin de un PrintWriter:
PrintWriter pw = new PrintWriter (new File(/tmp/f.txt));
Si el fichero no existe se crea uno nuevo, si existe se trunca su tamao a cero.

PrintWriter pw2 =
new PrintWriter (new FileOutputStream(/tmp/f.txt, true));
Si el fichero no existe se crea uno nuevo, si existe se mantiene, ya que se escribir
aadiendo (append) al final del mismo.

Si el fichero especificado no es accesible en el sistema de archivos, el constructor de


PrintWriter
o
de
FileOutputStream
puede
lanzar
la
excepcin
FileNotFoundException, que deber ser tratada.

Programacin 2014/15 - Tema 8

20

La clase PrintWriter
Ejemplo de programa que usa PrintWriter:
import java.io.* ;
public class TestPrintWriter {
public static void main (String [] args) {
String fichero = "file2.txt" ;
try {
PrintWriter pw = new PrintWriter (new File (fichero));
pw.print ("El veloz murcilago hind") ;
pw.println (" coma feliz cardillo y kiwi") ;
pw.println (4.815162342) ;
pw.close () ;
} catch (FileNotFoundException e) {
System.err.println("Problemas al abrir el fichero "+fichero) ;
}
}
}

Programacin 2014/15 - Tema 8

21

La clase PrintWriter
Escribe un programa Java que cree un fichero de texto cuyo nombre se elegir en la
ejecucin y que tenga como contenido la frase Esto es una prueba.

Programacin 2014/15 - Tema 8

22

La clase PrintWriter
Escribe un programa Java que cree un fichero de texto cuyo nombre se elegir en la
ejecucin y que tenga como contenido la frase Esto es una prueba.
import java.io.* ;
public class EjemploPrintWriter {
public static void main (String [] args) {
String fichero;
Scanner tec = new Scanner (System.in) ;
System.out.print ("Dame el nombre del fichero: ") ;
fichero = tec.nextLine() ;
try {
PrintWriter fi = new PrintWriter (new File (fichero));
fi.println ("Esto es una prueba") ;
fi.close () ;
} catch (FileNotFoundException e) {
System.err.println("Problemas al abrir el fichero "+fichero) ;
}
}
}

Programacin 2014/15 - Tema 8

23

2. Ficheros de texto: lectura


La clase java.util.Scanner:
Escner de texto que permite procesar tipos primitivos y cadenas.
Divide los datos de entrada en tokens (elementos individuales) que sern procesados de
forma individual
Mtodo / Constructor

Descripcin

Scanner (File f)
Mtodo / Constructor

Crea un nuevo Scanner a partir de un objeto de tipo File. Lanza


FileNotFoundException si elDescripcin
fichero no es accesible.

Scanner
(String
src)
Scanner(File
source)

Crea un
Scanner
leer datos
partir del String.
Crea
unnuevo
nuevo
Scannerpara
a partir
de una File

boolean
hasNextsrc)
()
Scanner(String

Devuelve
true Scanner
si hay al
menos
un token
en del
la entrada.
Crea
un nuevo
para
leer datos
a partir
String Lanza la excepcin

booleanhasNextInt
hasNext() ()
boolean

Devuelve
true sisihay
al menostoken
un token
la entrada
Devuelve true
el siguiente
de laen
entrada
se puede interpretar como un
entero.
Devuelve true si el siguiente token de la entrada es un entero

boolean hasNextInt()
int nextInt ()

int nextInt()

IllegalStateException si el flujo del Scanner estaba cerrado.

Devuelve el siguiente token de la entrada como un int siempre que se trate de un


int. De noelserlo,
lanza InputMismatchException.
Devuelve
siguiente
token de la entrada como un entero. De no serlo,

lanza
InputMismatchException

next ()
String

Devuelve

String next()
StringnextLine
nextLine() ()
String
void close()
void close ()

el siguiente token de la entrada ledo como un String. Lanza


NoSuchElementException
quedan ms elementos por leer. Lanza
Devuelve
el siguiente token desila no
entrada
IllegalStateException si el flujo del Scanner estaba cerrado.
Devuelve el resto de la lnea, desde el punto de lectura actual
Devuelve el resto de la lnea, desde el punto de lectura actual, descartando el salto de
lnea. Devuelve el resultado como un String.

Cierra el Scanner
Cierra el Scanner

Programacin 2014/15 - Tema 8

24

Ficheros de texto (lectura): excepciones

o Si el fichero especificado no est accesible en el sistema de archivos, se lanza la


excepcin (checked) FileNotFoundException.

Esta excepcin deber ser tratada.

o Algunos de los mtodos de lectura como nextInt(), nextDouble(), etc, pueden


lanzar
una
excepcin
(unchecked)
de
formato
incorrecto:
InputMismatchException o, si se intenta acceder ms all del final del fichero
se provocar la NoSuchElementException.
o El tratamiento de estas excepciones permitir recuperar el proceso si se intenta leer
un dato mal formateado o inexistente.

Programacin 2014/15 - Tema 8

25

Ficheros de texto (escritura): ejemplo


Ejemplo de uso de PrintWriter y de Scanner: Programa que escribe 10 enteros en
un fichero de texto y luego los lee antes de mostrarlos por pantalla.
import java.io.* ;
import java.util.Scanner ;
class TestPrintWriter1 {
public static void main (String[] args) {
String fichero = "file1.txt" ;
try {
PrintWriter pw = new PrintWriter (new File (fichero)) ;
for (int i = 0; i < 10 ; i++)
pw.println (i) ;
pw.close() ;
Scanner scanner = new Scanner (new File (fichero)) ;
while (scanner.hasNext())
System.out.println("Valor leido: " + scanner.nextInt()) ;
scanner.close() ;
} catch (FileNotFoundException e) {
System.err.println ("Problemas al abrir el fichero " + fichero) ;
}
}
}

Programacin 2014/15 - Tema 8

26

Ficheros de texto (lectura): ejemplo


Ejemplo de uso de Scanner: Programa que lee de un fichero de texto.
import java.io.* ; import java.util.Scanner ;
public class TestScanner {
public static void main (String[] args) {
System.out.println ("Leeremos 3 nmeros y una lnea de texto") ;
Scanner scan = null ;
try {
scan = new Scanner (new File ("cosas.txt"));
} catch (FileNotFoundException ex) {
System.err.println ("El fichero no existe." + ex.getMessage()) ;
System.exit(0) ;
}

}
}

int n1 = scan.nextInt() ;
int n2 = scan.nextInt() ;
int n3 = scan.nextInt() ;
scan.nextLine() ;
String linea = scan.nextLine() ;
System.out.println ("Los tres nmeros son: " + n1 + ", " + n2 + ", " + n3) ;
System.out.println ("La lnea es: " + linea) ;
12
scanner.close () ;
34
Multiplcate por
cero!

cosas.txt

Programacin 2014/15 - Tema 8

27

Problema Ficheros de texto

o Tenemos un fichero de texto que contiene en cada lnea el nombre de un


participante en una carrera y su posicin final. Se pide mostrar por pantalla esos
valores.

Programacin 2014/15 - Tema 8

28

o Tenemos un fichero de texto que contiene en cada lnea el nombre de un


participante en una carrera y su posicin final. Se pide mostrar por pantalla esos
valores.

import java.io.* ;
import java.util.* ;
public class Test {
public static void main (String[] args) {
try {
Scanner scan = new Scanner (new File ("carreras.txt")) ;
while (scan.hasNextLine()) {
String linea = scan.nextLine() ;
String [] tokens = linea.split (" ") ;
System.out.println (tokens[0] + " : " + tokens[1]) ;
}
scan.close() ;
} catch (FileNotFoundException ex) {
System.out.println ("El fichero no existe. " + ex) ;
}
}
}

Programacin 2014/15 - Tema 8

29

Problema Ficheros de texto

Construye un programa en el que, recibiendo un fichero de caracteres y una palabra


almacenada en una cadena de caracteres, muestre como resultado el nmero de
veces que aparece dicha palabra en el fichero.

Programacin 2014/15 - Tema 8

30

import java.io.* ;
import java.util.Scanner ;
public class ContadorPalabras {
public static void main(String[] args){
Scanner scanner = null ;
Scanner teclado = new Scanner (System.in) ;
int cont = 0 ;

Problema Ficheros de texto

Construye un programa en el que, recibiendo un fichero de caracteres y una palabra


almacenada
en una cadena de caracteres, muestre como resultado el nmero de
try {
("Nombre
fichero: ") ;
vecesSystem.out.print
que aparece dicha palabra
en eldel
fichero.
String nombre = teclado.nextLine() ;
scanner = new Scanner (new File(nombre)) ;
} catch (FileNotFoundException ex) {
System.err.println ("El fichero no existe." + ex.getMessage()) ;
System.exit(0) ;
}
System.out.print ("Que palabra buscas: ") ;
String palabra = teclado.nextLine() ;
while (scanner.hasNext()) {
String cad = scanner.next() ;
if (cad.equals(palabra))
cont++ ;
}
scanner.close() ;
System.out.println ("La palabra "+palabra+" aparece "+cont+" veces") ;

}
}

Programacin 2014/15 - Tema 8

31

Problema Ficheros de texto

Construye un programa que cuente el nmero de lneas que aparecen en un archivo de


texto e imprima dicho nmero por pantalla.

Programacin 2014/15 - Tema 8

32

import java.io.* ;
Problema
Ficheros de texto
import java.util.Scanner
;
public class ContadorPalabras {
public static void main(String[] args) {
Scanner scanner = null ;
Scanner teclado = new Scanner (System.in) ;
Construye
un programa
int cont
= 0 ; que cuente el nmero de lneas que aparecen en un archivo de
texto e imprima dicho nmero por pantalla.
try {
System.out.print ("Nombre del fichero: ") ;
String nombre = teclado.nextLine() ;
scanner = new Scanner (new File(nombre)) ;
} catch (FileNotFoundException ex) {
System.err.println("El fichero no existe."+ex.getMessage()) ;
System.exit(0) ;
}
while (scanner.hasNext()) {
String cad = scanner.nextLine() ;
cont++ ;
}
scanner.close() ;
System.out.println ("El nmero de lneas es " + cont) ;
}
}

33

Programacin 2014/15 - Tema 8

3. Ficheros binarios
o Con ellos es posible almacenar y recuperar, de forma codificada, datos en ficheros (as,
un int ocupar 4 bytes, un double 8, etc.).
o En general se debe seguir una poltica en el almacenamiento que facilite despus la
recuperacin adecuada de la informacin.
o Por ejemplo: si se salva el contenido de una agenda, almacenando los valores
elementales de cada uno de sus componentes, se puede seguir una poltica de
agrupacin de la informacin en los denominados registros (grupos de informacin
similar que se repiten):
Nombre

Direccin

Telfono

Nombre

Direccin

campo
registro

registro
fichero

Telfono

Programacin 2014/15 - Tema 8

34

3. Ficheros binarios
o Para la lectura o escritura de un fichero binario se debe:
1) Crear un File con el origen / destino de datos.
2) Envolverlo en un FileInputStream / FileOutputStream para crear un
flujo de datos desde / hacia el fichero.
3) Envolver el objeto anterior en un ObjectInputStream /
ObjectOutputStream para poder leer / escribir tipos de datos primitivos u
objetos del flujo de datos.

o Posteriormente, para escribir o leer se deben usar mtodos como:


o writeInt, writeDouble, writeBoolean, writeObject, etc. (en escritura)
o readInt, readDouble, readBoolean, readObject, etc. (en lectura)

35

Programacin 2014/15 - Tema 8

Ficheros binarios
La clase ObjectOutputStream contiene mtodos para escribir tipos primitivos y
objetos a un stream.
Existen mtodos anlogos en ObjectInputStream para leerlos.
Mtodo
Mtodo
/ Constructor
/ Constructor

Descripcin
Descripcin

ObjectOutputStream
(FileOutputStream
out)
un objeto
nuevo objeto
partir
del stream
de salida
ObjectOutputStream(FileOutputStream
out)
Crea unCrea
nuevo
a partiradel
stream
de salida
voidwriteInt(int
writeInt
void
v) (int v)

el entero
v al stream
decomo
salida4como
EscribeEscribe
el entero
v al stream
de salida
bytes 4 bytes

void
writeLongv)(long v)
void writeLong(long

long
v al stream
decomo
salida8como
EscribeEscribe
el long el
v al
stream
de salida
bytes 8 bytes

void
writeUTF (String
str)
void writeUTF(String
str)

elstr
String
str portable
en formato
portable
EscribeEscribe
el String
en formato
(UTF8
mod.)(UTF8 mod.)

void
writeDouble (double
v)
void writeDouble(double
v)

el double
v aldestream
salida
como 8 bytes
EscribeEscribe
el double
v al stream
salida de
como
8 bytes

void
writeObject obj)
(Object obj)
void writeObject(Object

el obj
Object
objde
al salida.
streamLodeque
salida,
lo que
EscribeEscribe
el Object
al stream
provoca
la provoca
la de
escritura
todos de
loslosobjetos
que obj(yest
escritura
todos losdeobjetos
que obj de
estlos
compuesto
as
recursivamente).
compuesto (y as recursivamente).

Los mtodos de escritura pueden lanzar la excepcin IOException.

Programacin 2014/15 - Tema 8

36

Ficheros binarios: tratamiento de las excepciones


o El constructor de FileOutputStream/FileInputStream puede lanzar la
excepcin FileNotFoundException.
Si el fichero especificado no existe en el sistema de archivos.
o Los mtodos de escritura de ObjectOutputStream y los mtodos de lectura de
ObjectInputStream pueden lanzar alguna excepcin de tipo IOException o de
alguna subclase de la misma.
Si ocurre algn problema al escribir el fichero (permisos, hw, etc.).
Si la clase del objeto que se quiere escribir no es serializable.
o Adems, el mtodo readObject() de la clase ObjectInputStream puede lanzar
una ClassNotFoundException si no se puede determinar la clase del objeto que
se intenta leer.
o Todas estas excepciones deben ser gestionadas mediante el uso adecuado de un
bloque try-catch.

Programacin 2014/15 - Tema 8

37

Ficheros binarios: ejemplo


Ejemplo: Programa que escribe datos en un fichero binario y posteriormente los lee antes de
mostrarlos.
import java.io.* ;
class Calificaciones {
public static void main(String[] args){
String fichero = "calificaciones.data";
String nombre = "PRG" ;
int conv = 1 ;
double nota = 7.8 ;
try {
ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream (fichero)) ;
out.writeUTF(nombre) ; out.writeInt(conv) ; out.writeDouble(nota) ;
out.close() ;
ObjectInputStream in = new ObjectInputStream(new FileInputStream(new File(fichero))) ;
System.out.println ("Valor ledo de nombre: " + in.readUTF()) ;
System.out.println ("Valor ledo de convocatoria: " + in.readInt()) ;
System.out.println ("Valor ledo de nota: " + in.readDouble()) ;
in.close() ;
} catch (FileNotFoundException e) {
System.err.println ("Problemas con el fichero " + fichero + "." + e.getMessage()) ;
} catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + fichero) ;
}
}
}

Programacin 2014/15 - Tema 8

38

Determinar el final de fichero


o A veces no se conoce inicialmente el nmero de elementos que contiene un fichero.
o Si se intenta leer ms all del final del mismo se producir una excepcin
(IOException) que permitir, si es tratada, gestionar la situacin.
o Adems, en el caso de los ObjectInputStream ocurre que cuando se leen
valores elementales se produce, al intentar acceder ms all del final del fichero, la
excepcin EOFException (subclase de IOException).
o En conclusin: es posible tratar todos los elementos de un fichero leyndolos uno a
uno hasta que se produce la excepcin correspondiente.
o El ejemplo siguiente muestra esta tcnica que, adems, se puede utilizar en
cualquier flujo que lance una excepcin similar.

Programacin 2014/15 - Tema 8

39

Determinar el final de fichero


o El ejemplo siguiente muestra la lectura de un fichero de int para el que no es conocido
el nmero de valores que contiene.
o Los valores ledos se escriben uno tras otro en la pantalla y al llegar al final del fichero se
escribe un aviso.
public static void leer(String fich) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fich)) ;
try {
while (true) {
int val = ois.readInt() ;
System.out.println(val) ;
}
} catch (EOFException ef) {
System.out.println("Final del fichero") ;
}
ois.close() ;
} catch (IOException fex) {
System.err.println ("Error al recuperar: " + fex.getMessage()) ;
}
}

Programacin 2014/15 - Tema 8

40

Ficheros binarios: ejemplo


Ejemplo: Programa que escribe datos en un fichero binario y posteriormente los lee
antes de mostrarlos. Ahora lo extendemos con ms datos.

Programacin 2014/15 - Tema 8

41

Ficheros binarios: ejemplo


Ejemplo: Programa que escribe datos en un fichero binario y posteriormente los lee
antes de mostrarlos. Ahora lo extendemos con ms datos. (1 / 3)
import java.io.* ;
import java.util.* ;
class ficheroBinario {
public static void main (String[] args) {
String fichero = "calificaciones.data" ;
try {
ObjectOutputStream datosFichero = new ObjectOutputStream
(new FileOutputStream (fichero)) ;
meterDatos (datosFichero) ;
datosFichero.close() ;
ObjectInputStream salida = new ObjectInputStream (new FileInputStream (fichero)) ;
verResultados (salida) ;
salida.close() ;
} catch (FileNotFoundException e) {
System.err.println("Problemas con el fichero " + fichero + "." + e.getMessage()) ;
} catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + fichero) ;
}
}

Programacin 2014/15 - Tema 8

42

Ficheros binarios: ejemplo


Ejemplo: Programa que escribe datos en un fichero binario y posteriormente los lee
antes de mostrarlos. Ahora lo extendemos con ms datos. (2 / 3)
public static void meterDatos (ObjectOutputStream fic) {
Scanner teclado = new Scanner (System.in).useLocale (Locale.US) ;
try {
System.out.println ("Cuantos datos vas a introducir: ") ;
int numero = teclado.nextInt() ;
for (int i=1; i<=numero; i++) {
System.out.println ("Datos del elemento " + i + ":") ;
teclado.nextLine() ;
System.out.print ("Nombre: ") ;
String nombre = teclado.nextLine() ;
System.out.print ("Convocatoria: ") ;
int conv = teclado.nextInt() ;
System.out.print ("Nota: ") ;
double nota = teclado.nextDouble() ;
fic.writeUTF (nombre) ;
fic.writeInt (conv) ;
fic.writeDouble (nota) ;
}
// fic.close();
He metido en main esta instruccin. Vale en cualquiera de los dos sitios
} catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + fic) ;
}
}

Programacin 2014/15 - Tema 8

43

Ficheros binarios: ejemplo


Ejemplo: Programa que escribe datos en un fichero binario y posteriormente los lee
antes de mostrarlos. Ahora lo extendemos con ms datos. (3 / 3)

public static void verResultados (ObjectInputStream fi) {


try {
while (true) {
System.out.println ("Valor ledo de nombre: " + fi.readUTF()) ;
System.out.println ("Valor ledo de convocatoria: " + fi.readInt()) ;
System.out.println ("Valor ledo de nota: " + fi.readDouble()) ;
}
} catch (EOFException ex) {
System.out.println ("Se acab el fichero binario") ;
} catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + fi) ;
}
}
}

Programacin 2014/15 - Tema 8

44

Ficheros binarios: ejemplo


Ejemplo: Programa que lee datos de un fichero binario y posteriormente los muestra
por pantalla.
import java.io.* ;
import java.util.* ;
public class ficheroBinario {
public static void main (String [] args) {
Scanner teclado = new Scanner(System.in) ;
System.out.print ("Nombre del fichero: ") ;
String fichero = teclado.nextLine() ;
String ciudad ;
int nDatos ;
float [] lluvias ;
try {
ObjectInputStream entrada = new ObjectInputStream (new FileInputStream(fichero)) ;
ciudad = entrada.readUTF() ;
nDatos = entrada.readInt() ;
lluvias = new float [nDatos] ;
for (int i=0; i<lluvias.length; i++)
lluvias[i] = entrada.readFloat() ;
entrada.close() ;
System.out.println ("Ciudad: " + ciudad) ;
System.out.println ("Nmero de datos: "+ nDatos) ;
for (int i=0; i<lluvias.length; i++)
System.out.println ("Dato[" + (i+1) + "[": " + lluvias[i]) ;
} catch (IOException ex) {
System.err.println ("Problemas al leer: " + ex) ;
}
}
}

Programacin 2014/15 - Tema 8

45

Recomendaciones para trabajar con ficheros


o Los ficheros (streams) siempre han de ser explcitamente cerrados (mtodo
close) despus de ser utilizados.
o En particular, un fichero sobre el que se ha escrito, debe ser cerrado antes de poder
ser abierto para lectura (para garantizar la escritura de datos en el disco).
o Si el programador no cierra de forma explcita el fichero, Java lo har, pero si el
programa termina anormalmente (se va la luz!) y el stream de salida usaba
buffering, el fichero puede estar incompleto o corrupto.
o Es importante gestionar las excepciones en los procesos de E/S:
Ficheros inexistentes (FileNotFoundException).
Fallos de E/S (IOException).
Incoherencias de tipos al usar Scanner (InputMismatchException).
Condicin de final de fichero (EOFException).

Programacin 2014/15 - Tema 8

46

Conclusiones
o El uso de ficheros permite que la informacin sobreviva a la ejecucin de los programas
mediante el uso de almacenamiento secundario.

o Java permite la creacin de ficheros binarios independientes de la plataforma y ficheros


de texto usando mecanismos basados en flujos (streams).

o La forma ms cmoda para interactuar con ficheros de texto:


PrintWriter (escritura), Scanner (lectura).

o La forma ms cmoda para interactuar con ficheros binarios secuenciales de valores


elementales y/o objetos:
ObjectOutputStream (escritura), ObjectInputStream (lectura)

Programacin 2014/15 - Tema 8

47

Problema
o Escribe un programa que lea un fichero de texto de nombre entrada.txt que
contiene en cada lnea la parte real e imaginaria de un nmero complejo y genere
otro fichero de texto de nombre salida.txt en el que cada lnea sea el mdulo de
los nmeros complejos contenidos en el fichero de entrada.

Programacin 2014/15 - Tema 8

48

import java.io.* ;
import java.util.Scanner ;
class FicherosTexto {
public static void main (String[] args) {
String fichero1 = "entrada.txt" ;
String fichero2 = "salida.txt" ;
int i1, i2;
try {
Scanner scan = new Scanner(new File(fichero1)) ;

// para lectura

PrintWriter pw = new PrintWriter(new File(fichero2)) ;

// para escritura

while (scan.hasNext()) {
i1 = scan.nextInt() ;
i2 = scan.nextInt() ;
String basura = scan.nextLine() ;
double res = Math.sqrt (i1*i1+i2*i2) ;
pw.println (res) ;
}
pw.close() ;
scan.close() ;
}
} catch (FileNotFoundException e) {
System.err.println("Problemas al abrir el fichero " + fichero1) ;
}
}
}

Programacin 2014/15 - Tema 8

49

Problema
o Tenemos un archivo con informacin de una consulta electoral. El primer valor
almacenado indica el nmero de mesas electorales. A partir de ah, para cada mesa se
dispone de su identificador (cadena de caracteres) y del nmero de votos que cada uno
de los cinco partidos presentados (A, B, C, D y E) ha obtenido en esa mesa y el nmero
completo de personas censadas en esa mesa con derecho a voto.

Construye un programa en Java que nos muestre por pantalla el nmero de votos totales
de los partidos y para cada mesa el nmero de personas que no ha votado.
(2.25 puntos)

1): como fichero de texto


2): como fichero binario

Programacin 2014/15 - Tema 8

import java.io.* ;

50

1) Como fichero de texto

import java.util.Scanner ;
class FicherosTexto {
public static void main (String[] args) {
Scanner teclado = new Scanner (System.in) ;
System.out.print ("Nombre del fichero: ") ;
String nombre = teclado.nextLine() ;
try {
Scanner scan = new Scanner (new File(nombre)) ;
int num = scan.nextInt() ;
int [][] votacion = new int [num][6] ;
String [] mesas = new String [num] ;
for (int i=0; i<votacion.length; i++) {
String basura = scan.nextLine() ;
mesas[i] = scan.nextLine() ;
for (int j=0; j<votacion[0].length; j++)
votacion[i][j] = scan.nextInt() ;
}
scan.close() ;
int [] votos = new int [5] ;
calculo (votacion, votos) ;
mostrarResultados (votos) ;
mostrarAbstencion (mesas, votacion) ;
}

// para lectura

Programacin 2014/15 - Tema 8

51

catch (FileNotFoundException e) {
System.err.println ("Problemas al abrir el fichero " + nombre) ;
}
}
public static void calculo (int [][]resul, int [] v) {
for (int j=0; j<v.length; j++) {
v[j] = 0 ;
for (int i=0; i<resul.length; i++)
v[j] += resul[i][j] ;
}
}

public static void mostrarResultados (int [] vo) {


for (int i=0; i<vo.length; i++)
System.out.println ("Los resultados del partido "+i+" son " + vo[i]) ;
}

Programacin 2014/15 - Tema 8

52

public static void mostrarAbstencion (String [] m, int [][] vota) {


for (int i=0; i<vota.length; i++) {
int cont = 0 ;
for (int j=0; j<5; j++)
cont += vota[i][j] ;
int abstencion = vota[i][5] cont ;
System.out.println ("La abstencion de la mesa "+m[i]+" es "+abstencion) ;
}
}
}

Programacin 2014/15 - Tema 8

import java.io.* ;

53

2) Como fichero binario

import java.util.Scanner ;
class FicherosTexto {
public static void main (String[] args) {
Scanner teclado = new Scanner (System.in) ;
System.out.print ("Nombre del fichero: ") ;
String nombre = teclado.nextLine() ;
try {
ObjectInputStream entrada = new ObjectInputStream (new
FileInputStream (nombre)) ;
int num = entrada.readInt() ;
int [][] votacion = new int [num][6] ;
String [] mesas = new String [num] ;
for (int i=0; i<votacion.length; i++) {
mesas[i] = entrada.readUTF() ;
for (int j=0; j<votacion[0].length; j++)
votacion[i][j] = entrada.readInt() ;
}
entrada.close() ;
int [] votos = new int [5] ;
calculo (votacion, votos) ;
mostrarResultados (votos) ;
mostrarAbstencion (mesas, votacion) ;
}

Programacin 2014/15 - Tema 8

54

catch (FileNotFoundException e) {
System.err.println ("Problemas al abrir el fichero " + nombre) ;
}
catch (IOException e) {
System.err.println ("Problemas al utilizar el fichero " + nombre) ;
}
}
public static void calculo (int [][]resul, int [] v) {
for (int j=0; j<v.length; j++) {
v[j] = 0 ;
for (int i=0; i<resul.length; i++)
v[j] += resul[i][j] ;
}
}

public static void mostrarResultados (int [] vo) {


for (int i=0; i<vo.length; i++)
System.out.println ("Los resultados del partido "+i+" son " + vo[i]) ;
}

Programacin 2014/15 - Tema 8

55

public static void mostrarAbstencion (String [] m, int [][] vota) {


for (int i=0; i<vota.length; i++) {
int cont = 0 ;
for (int j=0; j<5; j++)
cont += vota[i][j] ;
int abstencion = vota[i][5] cont ;
System.out.println ("La abstencion de la mesa "+m[i]+" es "+abstencion) ;
}
}
}

Programacin 2014/15 - Tema 8

56

import java.io.* ;
Pasar de fichero texto a binario
import java.util.Scanner ;
class FicherosTexto {
public static void main (String[] args) {
Scanner teclado = new Scanner (System.in) ;
System.out.print ("Nombre del fichero: ") ;
String nombre = teclado.nextLine() ;
String nombre2 = "salida.data" ;
try {
Scanner scan = new Scanner (new File(nombre)) ;
ObjectOutputStream datosFichero = new ObjectOutputStream (new FileOutputStream (nombre2));
int num = scan.nextInt() ;
datosFichero.writeInt(num) ;
int [][] votacion = new int [num][6] ;
String [] mesas = new String [num] ;
for (int i=0; i<votacion.length; i++) {
String basura = scan.nextLine();
mesas[i] = scan.nextLine() ;
datosFichero.writeUTF(mesas[i]) ;
for (int j=0; j<votacion[0].length; j++) {
votacion[i][j] = scan.nextInt() ;
datosFichero.writeInt(votacion[i][j]) ;
}
}
scan.close() ;
datosFichero.close() ;
int [] votos = new int [5] ;
calculo (votacion, votos) ;
mostrarResultados (votos) ;
mostrarAbstencion (mesas, votacion) ;
}
catch (FileNotFoundException e) {
System.err.println("Problemas al abrir el fichero " + nombre) ;
}
catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + nombre) ;
}
}

Programacin 2014/15 - Tema 8

57

Problema
o Dado un fichero binario en el que estn contenidos todos los alumnos del primer
curso de la asignatura Programacin de la ETSIT con la siguiente informacin:
Nombre y nota,
construye un programa en Java que escriba en un fichero de texto los alumnos
aprobados (con nota mayor o igual a 5).
(1.5 puntos)

Programacin 2014/15 - Tema 8

58

import java.io.* ;
import java.util.* ;
class FicheroNotas {
public static void main (String[] args) {
Scanner teclado = new Scanner (System.in) ;
System.out.print ("Nombre del fichero inicial: ") ;
String nombre1 = teclado.nextLine() ;
System.out.print ("Nombre del fichero final: ") ;
String nombre2 = teclado.nextLine() ;
try {
ObjectInputStream datosFichero = new ObjectInputStream (new FileInputStream (nombre1));
PrintWriter grabar = new PrintWriter (new File(nombre2)) ;
while (true) {
String nombre = datosFichero.readUTF() ;
int nota = datosFichero.readInt() ;
if (nota>=5) {
grabar.println (nombre) ;
grabar.println (nota) ;
}
}
// grabar.close() ;
Nunca se alcanza esta instruccin por culpa del while (true)
// datosFichero.close() ;
}
catch (FileNotFoundException e) {
System.err.println ("Problemas al abrir el fichero " + nombre1) ;
}
catch (IOException e) {
System.err.println ("Problemas al escribir en el fichero " + nombre2) ;
}
}
}

Das könnte Ihnen auch gefallen