Practica 6
Practica 6
Practica 6
Introducci on a la entrada/salida en
Java
Abril de 2014
Complementos de Programaci on
Curso 2013/2014
Contents
1 Introducci on 3
2 Clase File 3
3 Entrada/salida de cheros de texto 5
3.1 Escribiendo datos con PrintWriter . . . . . . . . . . . . . . 6
3.2 Leyendo datos con Scanner . . . . . . . . . . . . . . . . . . 8
4 Clases para entrada/salida binaria 9
4.1 FileInputStream y FileOutputStream . . . . . . . . . . . . . 12
4.2 DataInputStream y DataOutputStream . . . . . . . . . . . . 14
4.3 Entrada/salida de objetos . . . . . . . . . . . . . . . . . . . 16
4.3.1 Interfaz Serializable . . . . . . . . . . . . . . . . . . 18
Complementos de Programaci on Introducci on a la entrada/salida en Java 3
1 Introducci on
Java realiza entradas y salidas a trav es de streams (ujos de datos). Un
stream es una abstracci on que produce o consume datos.
Un ujo est a asociado con un dispositivo fsico a trav es del sistema de
E/S de Java. Un ujo puede abstraer distintos tipos de entrada: archivo
de disco, teclado, conexi on a red. Un ujo puede abstraer distintos tipos
de salida: consola, archivo de disco o conexi on a red.
Todos los ujos se comportan de la misma manera, incluso aunque
est en relacionados con distintos dispositivos fsicos: se usan las mismas
clases de Entrada/Salida y los mismos m etodos independientemente de
cual sea el dispositivo fsico. Con un stream la informaci on se traslada en
serie (car acter a car acter o byte a byte) a trav es de esta conexi on.
2 Clase File
Hasta ahora, siempre hemos guardado los datos de nuestro programa
en alguna estructura de datos alojada en la memoria principal de nue-
stro ordenador. Para poder almacenar los datos de forma permanente,
necesitamos guardarlos en un chero de disco u otro dispositivo de alma-
cenamiento.
La clase File es una abstraction para representar un chero o un di-
rectorio. Contiene m etodos para obtener las propiedades de un chero/directorio,
para renombrar y borrar cheros/directorios, para crear directorios, etc.
Sin embargo, esta clase no tiene m etodos para leer y escribir el contenido
de un chero. Un directorio se trata igual que un chero con una propiedad
adicional: una lista de nombres de cheros que se pueden examinar con el
m etodo String[] list(). La clase File proporciona un aislamiento
de la plataforma (por ej. si el separador de subdirectorios es \ o /). El
convenio en Java es usar /.
Al crear un objeto File no se crea un chero en disco. Podemos crear
un objeto File con cualquier nombre de chero, independientemente de
que exista o no. El m etodo exist() de la clase File permite comprobar
si existe.
Para crear un objeto File podemos usar un path absoluto o rela-
tivo. Pero es recomendable trabajar con path relativos al directorio actual,
para que el programa funcione independientemente del directorio d onde
lo tengamos guardado.
Constructores:
Complementos de Programaci on Introducci on a la entrada/salida en Java 4
File(String filename)
File(File folder, String filename)
File(String folder, String filename)
Ejemplos
File f1 = new File("/");
File f2 = new File("/","autoexec.bat");
File f3 = new File(f1,"autoexec.bat");
M etodos m as comunes:
boolean canRead(): Dice si tiene permiso para leerse
boolean canWrite(): Dice si tiene permiso para modi-
carse
File createTempFile(String prefix,String suffix)
File createTempFile(String prefix,String suffix,
File folder): Crea un chero temporal.
boolean delete(): Borra el chero
void deleteOnExit(): Marca el chero para borrarlo cuando
termine de ejecutarse la JVM. (util para limpiar los cheros tem-
porales)
boolean exists(): Devuelve true si el chero existe.
String getAbsolutePath(): Devuelve el path absoluto.
String getName(): Devuelve el nombre del chero. (parte
del path que sigue a la ultima barra)
String getParent(): Nombre de directorio donde est a el
chero. (null si es el root)
File getParentFile(): Similar a getParent() pero de-
vuelve un objeto File.
boolean isAbsolute(): Devuelve true si el chero tiene
un path absoluto y false si es un path relativo.
boolean isDirectory(): Devuelve true si el objeto es un
directorio.
boolean isFile(): Devuelve true si el objeto es un chero,
y false si es un directorio.
long lastModified(): Devuelve la fecha de ultima modi-
caci on.
boolean isHidden(): Devuelve true si el chero est a oculto.
long length(): Devuelve la longitud del chero (o 0 si no
existe o es un directorio).
String[] list()
String[] list(FilenameFilter filter): Si el chero
es un directorio, devuelve un array con los nombres de los
cheros que contiene.
Complementos de Programaci on Introducci on a la entrada/salida en Java 5
File[] listFiles()
File[] listFiles(FileFilter filter)
File[] listFiles(FilenameFilter filter): Similar
a list()
File[] listRoots(): Devuelve todos los directorios raiz
del sistema.
boolean mkdir(): Crea un directorio con el nombre de este
File.
boolean renameTo(File dest): Renombra el chero/directorio
con el nombre de dest. Devuelve true si la operaci on tuvo
exito.
boolean setReadOnly()
URL toURL(): Devuelve el path del chero como un objeto
URL en la forma file://pathname.
Ejercicio 1 Escribe el siguiente programa en el chero FileDemo.java y
comprueba su funcionamiento
import java.io.File;
class FileDemo {
static void print(String s) {
System.out.println(s);
}
public static void main(String args[]) {
File f1 = new File("FileDemo.java");
print("File Name: " + f1.getName());
print("Path: " + f1.getPath());
print("Abs Path: " + f1.getAbsolutePath());
print("Parent: " + f1.getParent());
print(f1.exists() ? "exists" : "does not exist");
print(f1.canWrite() ? "is writeable" : "is not writeable");
print(f1.canRead() ? "is readable" : "is not readable");
print("is " + (f1.isDirectory() ? "" : "not" + " a directory"));
print(f1.isFile() ? "is normal file" : "might be a named pipe");
print(f1.isAbsolute() ? "is absolute" : "is not absolute");
print("File last modified: " + f1.lastModified());
print("File size: " + f1.length() + " Bytes");
}
}
3 Entrada/salida de cheros de texto
Podemos usar la clase Scanner para leer datos de un chero de texto y la
clase PrintWriter para escribir datos en forma de texto en un chero.
La clase File no contiene m etodos para crear un chero o para leer/escribir
datos de/en un chero. Para ello necesitamos crear objetos de las clases
apropiadas de Java I/O. Hay dos tipos de cheros: de texto y binarios.
Los cheros de texto son esencialmente strings en disco, se pueden ver
y modicar con cualquier editor de texto tal como gedit, kwrite, kate, vi
en Linux, o Notepad de Windows. En esta secci on introducimos c omo
leer/escribir strings y valores num ericos de/en un chero de texto usando
las clases Scanner y PrintWriter.
Complementos de Programaci on Introducci on a la entrada/salida en Java 6
3.1 Escribiendo datos con PrintWriter
La clase java.io.PrintWriter puede usarse para crear un chero y
escribir datos en un chero de texto. Comenzamos creando un objeto de
esta clase:
PrintWriter output = new PrintWriter(filename);
Luego, podemos llamar a los m etodos print, println y printf
para escribir datos en el cheros.
PrintWriter(File file): Crea un objeto PrintWriter para
el objeto File especicado.
PrintWriter(String filename): Crea un objeto PrintWriter
para el chero especicado con el string.
void close(): Debe llamarse para cerrar el chero una vez hemos
terminado de escribir.
void print(String s): Escribe un string en el chero.
void print(char c): Escribe un caracter en el chero.
void print(char[] cArray): Escribe un array de caracteres
en el chero.
void print(int i): Escribe un int en el chero.
void print(long l): Escribe un long en el chero.
void print(float f): Escribe un float en el chero.
void print(double d): Escribe un double en el chero.
void print(boolean b): Escribe un boolean en el chero.
void println(): M etodo sobreescrito que funciona como print
a nadiendo un separador de lnea al nal.
void printf(Strint format, Object... args): Es simi-
lar a la funci on printf() del lenguaje C. format contiene los es-
pecicadores de formato de los argumentos (valor num ercio, car-
acter, boolean o string) a imprimir, y args (argumento de longitud
variable) se usa para pasar la lista de argumentos a imprimir. Un
especicador de formato esta formado por el signo % seguido de un
c odigo de conversi on
Los especicadores de formato m as usuales son:
Complementos de Programaci on Introducci on a la entrada/salida en Java 7
Ejemplo:
int contador = 5;
double cantidad = 45.56;
System.out.printf("contador es %d y cantidad es %f", count, amount);
Salida mostrada:
contador es 5 y cantidad es 45.560000
Ver http://docs.oracle.com/javase/tutorial/java/data/
numberformat.html para m as detalles.
Ejercicio 2 Escribe el siguiente programa en el chero WriteData.java,
complalo y ejec utalo. Comprueba el contenido del chero creado.
public class WriteData {
public static void main(String[] args) throws java.io.IOException {
java.io.File file = new java.io.File("scores.txt");
if (file.exists()) {
System.out.println("El fichero ya existe");
System.exit(0);
}
// Crear el fichero
java.io.PrintWriter output = new java.io.PrintWriter(file);
// Escribir salida formateada en el fichero
output.print("Jacinto Campos ");
output.println(90);
output.print("Buenaventura Olmedo ");
output.println(85);
// Cerrar el fichero
output.close();
}
}
El constructor de PrintWriter crea un nuevo chero si el chero
no existe. Si el chero ya exista, se borra el contenido del chero. La
llamada al constructor de PrintWriter puede lanzar una excepci on
de Entrada/Salida (FileNotFoundException) si el chero no puede
crearse.
Esta es una excepci on comprobada, que debe capturarse con
try-catch o bien declararla en la cabecera del m etodo d onde se puede
lanzar (main() en este caso).
Complementos de Programaci on Introducci on a la entrada/salida en Java 8
3.2 Leyendo datos con Scanner
La clase java.util.Scanner la hemos usado en pr acticas anteriores
para leer strings y valores primitivos desde consola. Un objeto Scanner
parte la entrada en tokens delimitados por espacios en blanco. Para leer
desde consola (teclado), hemos usado:
Scanner input = new Scanner(System.in);
Para leer de un chero crearemos un objeto Scanner para el chero
de la siguiente forma:
Scanner input = new Scanner(new File(filename));
Algunos constructores y m etodos de esta clase son:
Scanner(File source): Crea un Scanner que lee datos del
chero especicado.
Scanner(String source): Crea un Scanner que lee datos del
string especicado.
void close(): Cierra el Scanner.
boolean hasNext(): Devuelve true si el Scanner tiene m as
datos por leer.
String next(): Devuelve el siguiente token como un string.
String nextLine(): Devuelve una lnea acabada con el caracter
de n de lnea.
byte nextByte(): Devuelve el siguiente token como un byte.
short nextShort(): Devuelve el siguiente token como un short.
int nextInt(): Devuelve el siguiente token como un int.
long nextLong(): Devuelve el siguiente token como un long.
long nextDouble(): Devuelve el siguiente token como un double.
La llamada al constructor Scanner(File) puede lanzar una excepci on
de Entrada/Salida (FileNotFoundException) si el chero no existe.
Los m etodos next...() se conocen como m etodos de lectura de
tokens, porque leen tokens separados por un delimitados. Por defecto, los
delimitadores son los espacios en blanco. Los delimitadores se pueden
cambiar con el m etodo useDelimiter(String regex) que sirve para
denir un nuevo patr on para los delimitadores.
Al usar un m etodo de entrada de tokens, primero se saltan los delimita-
dores, y luego se lee un token hasta encontrar un delimitador. El token es
entonces convertido al tipo adecuado (byte, short, etc). Con next()
no se hace conversi on. Cuando el token no se empareja con el tipo, se
lanza una java.util.InputMismatchException.
Complementos de Programaci on Introducci on a la entrada/salida en Java 9
Los m etodos next() y nextLine() leen un string. El primero lee un
string delimitado por delimitadores, y el segundo lee una lnea acabada
con el car acter n de lnea.
Los m etodos de lectura de tokens no leen el delimitador que hay de-
spu es del token. Cuando llamamos a nextLine() despu es de usar otro
de los m etodos de lectura de tokens, se leen los caracteres que empiezan
en este delimitador y acaban con el n de lnea. El n de lnea es leido,
pero no se incluye en el string devuelto por nextLine().
Ejercicio 3 Escribe el siguiente programa en el chero ReadData.java,
complalo y ejec utalo comprobando el resultado.
import java.util.Scanner;
public class ReadData {
public static void main(String[] args) throws java.io.IOException {
// Crear objeto File
java.io.File file = new java.io.File("scores.txt");
// Crear un Scanner para el File
Scanner input = new Scanner(file);
// Leer datos del fichero
while (input.hasNext()) {
String firstName = input.next();
String lastName = input.next();
int score = input.nextInt();
System.out.println(
firstName + " " + lastName + " " + score);
}
// Cerrar el fichero
input.close();
}
}
Ejercicio 4 Hacer un programa (ReplaceText.java) que sustituya to-
das las ocurrencias de un determinado string por otro string en un chero
de texto. El programa se podr a ejecutar de la siguiente forma:
java ReplaceText ficheroOriginal nuevoFichero stringAntiguo stringNuevo
4 Clases para entrada/salida binaria
Los cheros binarios no pueden ser leidos usando un editor de texto,
deben leerse con los programas que los han creado. Por ejemplo, los pro-
gramas fuente de Java se escriben en cheros de texto, pero los cheros
class se almacenan en cheros binarios que lee la JVM.
Podemos ver un chero de texto como una secuencia de caracteres
y un chero binario como una secuencia de bytes. Los caracteres de
un chero de texto se codican usando una determinada codicaci on tal
como ASCII o Unicode. Por ejemplo el n umero entero decimal 199 se
almacena en un chero de texto como tres caracteres 1, 2, 9. El mismo
entero se almacena como el valor C7 en un chero binario ya que 199 es
igual al n umero hexadecimal C7 (199 = 12 16
1
+7). El procesamiento de
cheros binarios es m as eciente que el de los binarios.
Complementos de Programaci on Introducci on a la entrada/salida en Java 10
Java ofrece muchas clases para el procesamiento de entrada y salida.