Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manejo de flujos de entrada y salida
Se usan flujos en lugar de cadenas (Strings) ya que a diferencia de estos últimos, los flujos no
sólo pueden manejar arreglos de caracteres sino cualquier tipo de datos como: strings, tipos
primitivos y objetos.
La palabra flujo encierra una gran importancia ya que implica la condición de movimiento. Los
datos pueden fluir desde una fuente para ser consumidos por un programa, en ese caso se
habla de un flujo de entrada. Los datos también pueden fluir desde un programa hacia una
entidad externa (que puede ser incluso otro flujo), en ese caso se habla de un flujo de salida.
Las clases más básicas de E/S en java, son InputStream y OutputStream las cuales permiten
la lectura y escritura de bytes. Existen dos clases más abstractas, Reader y Writer , las cuales
son capaces de leer y escribir datos en un formato más primitivo.
Todas estas clases se encuentran en el paquete java.io, por lo que al principio del código
fuente tendremos que escribir la sentencia
import java.io.*;
La entrada/salida estándar (normalmente el teclado y la pantalla, respectivamente) se definen
mediante dos objetos que puede usar el programador sin tener que crear flujos específicos.
La clase System tiene un miembro denominado in que es una instancia de la clase InputStream
que representa al teclado o flujo de entrada estándar. Sin embrago, el miembro out de la clase
System es un objeto de la clase PrintStream, que imprime texto en la pantalla (la salida
estándar).
Para leer desde teclado solamente tenemos que llamar a la función readLine desde System.in.
try{
System.in.readLine();
}catch (IOException ex) { }
Obligatoriamente, el proceso de lectura ha de estar en un bloque try..catch.
Para imprimir en pantalla tenemos que llamar a la función print o printl desde System.out.
System.out.println("Número de bytes leídos "+numBytes);
Manejo de archivos
Organización de archivos:
En general existen dos tipos de archivos:
A. Archivos Secuenciales.‐ En este caso los datos se almacenan en forma consecutiva y
no es posible leer (recuerdan que significa esta operación) ningún registro (recuerdan
la nota de arriba) directamente es decir para leer el registro n, se deberá recorrer o
accesar los n‐1 registros anteriores.
B. Archivos Directos o Random.‐ Para este caso si se puede acceder o leer un renglón n
cualquiera.
Almacenamiento en archivos:
A. Modo Texto: en este caso los datos son almacenados usando código ascii y por tanto
son plenamente visibles usando cualquier editor.
B. Modo Binario: en este caso los datos son almacenados en notación hexadecimal y por
tanto se ocupa un editor binario para reconocerlos sin embargo un archivo binario es
más compacto que un archivo texto.
clase File
Proporciona información acerca de los archivos, de sus atributos, de los directorios, etc.
Constructores
File(String path)
File(String path, String name)
File(File dir, String name)
El parámetro path indica el camino hacia el directorio donde se encuentra el archivo, y name
indica el nombre del archivo. Los métodos más importantes que describe esta clase son los
siguientes:
• String getName()
• String getPath()
• String getAbsolutePath()
• boolean exists()
• boolean canWrite()
• boolean canRead
• boolean isFile()
• boolean isDirectory()
• boolean isAbsolute()
• long lastModified()
• long length()
• boolean mkdir()
• boolean mkdirs()
• boolean renameTo(File dest);
• boolean delete()
• String[] list()
• String[] list(FilenameFilter filter)
Ejemplo:
Intanciar un File
import java.io.File;
Creando un archivo vacio:
• Para crear un archivo vacio utilizamos el método: createNewFile();
• Utilizaremos el bloque try/cath porque la operación puede lanzar un excepción
IOException.
import java.io.File;
import java.io.IOException;
import java.io.File;
import java.io.File;
import java.io.File;
Archivos Binarios
DataOutputStream(),
DataInputStream(),
Para leer datos, se crea un objeto de la clase DataInputStream vinculándolo a un objeto
FileInputStream para leer desde un archivo en disco denominado pedido.txt.
FileInputStream fileIn=new FileInputStream("pedido.txt");
DataInputStream entrada=new DataInputStream(fileIn));
o en una sola línea
DataInputStream entrada=new DataInputStream(new FileInputStream("pedido.txt"));
La clase DataInputStream define diversos métodos readXXX que son variaciones del método
read de la clase base para leer datos de tipo primitivo
Boolean readBoolean();
byte readByte();
int readUnsignedByte();
short readShort();
int readUnsignedShort();
char readChar();
int readInt();
String readLine();
long readLong();
float readFloat();
double readDouble();
try {
//while(true){
while ((descripcion=entrada.readLine())!=null) {
//descripcion=entrada.readLine();
unidad=entrada.readInt();
entrada.readChar(); //lee el carácter tabulador
precio=entrada.readDouble();
System.out.println("has pedido "+unidad+" "+descripcion+" a
"+precio+" S/.");
total=total+unidad*precio;
}
System.out.println("Final del archivo");
}catch (EOFException e) {
System.out.println("Excepción cuando se alcanza el final del
archivo");
}
System.out.println("por un TOTAL de: "+total+" pts.");
entrada.close();
La clase DataOutputStream es útil para escribir datos del tipo primitivo de una forma
portable. Se crea un objeto de la clase DataOutputStream vinculándolo a un objeto
FileOutputStream.
FileOutputStream fileOut=new FileOutputStream("pedido.txt");
DataOutputStream salida=new DataOutputStream(fileOut));
o en una sola línea
DataOutputStream salida=new DataOutputStream(new FileOutputStream("pedido.txt"));
La clase DataOutputStream define diversos métodos writeXXX que son variaciones del método
write de la clase base para escribir datos de tipo primitivo
void writeBoolean(boolean v);
void writeByte(int v);
void writeBytes(String s);
void writeShort(int v);
void writeChars(String s);
void writeChar(int v);
void writeInt(int v);
void writeLong(long v);
void writeFloat(float v);
void writeDouble(double v);
Cuando se alcanza el final del archivo se produce una excepción del tipo EOFException.
Archivos de Texto
PrintWriter(),
BufferedReader(),
Para leer un archivo de texto se debe crear un objeto de la clase BufferedReader para la
escritura, vinculado a un objeto FileReader
FileReader flujoL = new FileReader (arch);
BufferedReader lectura = new BufferedReader (flujoL);
Utilizamos el método readLine( ). String m = lectura.readLine();
Se crea un objeto de la clase PrintWriter para la escritura, vinculado a un objeto
FileOutputStream
FileOutputStream flujoE = new FileOutputStream(arch,true);
// true indica que si existe el archivo al abrir el flujo agregue los datos al final
PrintWriter escritura = new PrintWriter(flujoE);
El metodo para grabar es println( ). escritura.println(“datos a grabar”);
El final del archivo se detecta cuando la función readLine devuelve null.
ELIMINAR en archivo
Eliminar o dar de baja en un archivo secuencial, implica tener que estar procesando dos
archivos a la vez, el segundo de ellos es un archivo temporal, un algoritmo de eliminación física
quedaría como:
Procedimiento:
Una segunda técnica, consiste en agregar un campo de estado (status) al registro, es agregar
un campo especial llamado status que puede ser de tipo char, con algunos caracteres de
control que se puedan cargar en el por ejemplo una 'a' significa que esta en alta, una 'b'
significa que esta en baja, etc.
Lo único que se tiene que hacer, es que cuando se agrega o manda el registro por primera vez
a disco, mandarlo cargado el campo de status con 'a' y estar validando con if siempre este
campo en cualquier proceso de búsqueda o condición o despliegue, si se encuentra cargado
con 'b' entonces solo avisar al usuario que esta de baja dicho registro.
MODIFICAR un archivo
Es un proceso similar a la eliminación, Se usan los dos archivos el original y el temporal y si el
registro es el buscado, se hace la operación correspondiente y después se graba en el
temporal.
Archivos Directos o Random.‐
Se dice que un archivo es de acceso u organización directa cuando para acceder a un registro n
cualesquiera no se tiene que pasar por los n‐1 registros anteriores.
Es decir, un archivo de acceso directo tiene que tener sus registros o renglones de un tamaño
fijo o predeterminado de antemano.
En java archivos de acceso directo pertenecen a la clase RANDOMACCESSFILE.
Un archivo de acceso directo permite posicionar el apuntador interno de registros, a cualquier
registro determinado sin necesidad de pasar por todos los registros anteriores, usando las
siguientes funciones.
1. Se crea un objeto de tipo FILE que se usa como parámetro para crear el archivo de
tipo RANDOMACCESSFILE.
2. Se crea el archivo: RandomAccessFile archivo=new
RandomAccessFile(arch,"rw");
a. El primer parámetro o argumento en esta función es la unidad de disco y el
nombre del archivo.
b. El segundo parámetro o argumento es llamado modo y es una de los varios
modos que podemos usar.
Value Meaning
"r" Open for reading only. Invoking any of the write methods of the resulting
object will cause an IOException to be thrown.
"rw" Open for reading and writing. If the file does not already exist then an
attempt will be made to create it.
"rws" Open for reading and writing, as with "rw", and also require that every
update to the file's content or metadata be written synchronously to the
underlying storage device.
"rwd" Open for reading and writing, as with "rw", and also require that every
update to the file's content be written synchronously to the underlying
storage device.
Recordar que un archivo directo tiene un tamaño de registro predefinido y es importante que
dicho tamaño se respete, para el caso de las variables strings dentro del código se deben
ajustar a ‘n’ caracteres, si la string es mas corta que dicho tamaño se tendrá que ampliar con
caracteres en blanco " ", si el tamaño es mas grande la string se tendrá que recortar con el
método substring().
También es importante recordar que java grabara cada carácter de la string usando dos(2)
bites en disco, es decir si son 25 caracteres utilizara 50 para la string y 4 bytes por cada entero,
es importante conocer el tamaño de registros grabados en disco porque esta información se
usa ampliamente en los programas.
Se recomienda que las claves sigan la secuencia 0,1,2,3,4,5.....
Usando archivo.seek() es posible posicionarse en cualquier byte del archivo. El formato usado
seek() es:
archivo.seek((long)(clave)* tamañoderegistro));
ELIMINACION a un archivo
En archivos directos no se puede ni se debe eliminar físicamente registros de los archivos
porque la clave del registro esta enlazada directamente a la posición que dicho registro tiene
en disco y no seria muy conveniente estarle cambiando la matricula al alumno cada rato o el
número de serie al auto, etc.
Es por eso que se emplea la técnica de incluir un campo de estado, status o bandera en el
registro y conforme se va cargando el registro y antes de mandarlo a disco se le agrega a dicho
campo el carácter 'A' ‐‐>alta, así que cuando se quiera una baja solo se pondría dicho campo
en 'B' y todos los programas de lectura, búsqueda y filtros deberán revisar esta campo de
estado antes de hacer algo con el registro.