Download - Temas programacion java_3
UNIDAD 5: JAVA REGISTROS Y ARCHIVOS SECUENCIALES TEMA 2: REGISTROS JAVA
Ya se ha visto como variables simples pueden almacenar una sola pieza de información y como arreglos pueden almacenar un conjunto de ellas del mismo tipo y al mismo tiempo, estos dos mecanismos pueden manejar una gran variedad de situaciones, pero a menudo se necesita trabajar sobre datos de diversos tipos, en este caso ni variables escalares ni arreglos son adecuados.
Para resolver estos problemas los lenguajes de programación proveen de un tipo de dato especial llamado registros.
Un registro es una variable especial que tiene la capacidad de almacenar datos de diferentes tipos.
Sin embargo JAVA usa en su lugar una CLASE.
Este método tiene la ventaja de que además de incluir los campos tradicionales de un registro (en forma de atributos) también puede incorporar una serie de métodos que permiten procesar de manera mas fácil los campos o atributos de la clase.
Ejemplo;
public class alumno{
void alumno(){};
static String nombre= new String();
static int edad;
void inicializar(){
alumno.nombre=“pepe el toro”;
alumno.edad=18; };
void desplegar(){
System.out.println(alumno.nombre);
System.out.println(alumno.edad);
};
} termina la clase Programa 21.java ; import java.io.*; public class prog21{ public static void main(String[] args) { alumno.inicializar();
alumno.desplegar(); } cierra main } cierra clase public class alumno{ void alumno(){}; static String nombre= new String(); static int edad; static void inicializar(){ alumno.nombre=“pepe el toro”; alumno.edad=18; }; static void desplegar(){ System.out.println(alumno.nombre); System.out.println(alumno.edad); }; } termina la clase
corrida:
Para indicar a “java” durante cualquier proceso que la variable a utilizar es un campo de una clase se deberá utilizar el siguiente formato.
nomclase.nombredelcampo
TEMA 3: JAVA ARCHIVOS (INTRODUCCION)
Si bien es cierto que ya se pueden manejar gran cantidad de datos del mismo y diferente tipo al mismo tiempo, el problema es que al terminar de ejecutarse el programa los datos se pierden.
De esta situación nace el concepto de archivos que son medios que facilita el lenguaje para almacenar los datos en forma permanente normalmente en los dispositivos de almacenamiento standar.
En general es necesario entender algunos conceptos elementales de sistemas de archivos tradicionales.
Como nota a tomar en cuenta los datos que se van almacenando en un archivo de disco se almacenan en renglones consecutivos y cada renglón en disco se conoce como registro del archivo favor de no confundir el concepto de registro de archivo y registro
o estructura como variable ya analizada son dos cosas totalmente diferentes aunque se llamen igual. Operaciones básicas con archivos:
1. ESCRIBIR O GRABAR: Es la operación mas elemental con un archivo consiste en
tomar un o unos datos en variables de cualquier tipo (escalar, mezcla de datos,
arreglo, estructuras) y almacenarlas en un archivo de datos en disco.
2. LEER: Operación consistente en sacar los datos del archivo en disco y mandarlo
o cargar la variable respectiva Organización de archivos: En general existen dos tipos de archivos:
1. 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.
2. Archivos Directos o Random.- Para este caso si se puede acceder o leer un renglón n cualquiera.
Tipo de archivos: A) En general, existen tantos tipos de archivos como tipos de datos existen es decir existen archivos de bytes, de chars, de ints, de floats, etc.
ATENCION: Ya que se decide utilizar algún archivo especifico de datos (caracteres, strings, formateados, registros o arreglos) solo utilizar las funciones de escritura y lectura de ese tipo de archivo por ningún motivo mezcle funciones de lectura y escritura de otro tipo de archivos.
Almacenamiento en archivos:
1. Modo Texto: en este caso los datos son almacenados usando código ascii y por
tanto son plenamente visibles usando cualquier editor.
2. 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.
TEMA 4: JAVA ARCHIVOS SECUENCIALES
1. Existen además muchas otras operaciones asociadas a archivos las más elementales son:
1.- Creación de Archivo.- En este proceso se pretende solamente crear un archivo nuevo en disco, con su nombre, tipo y especialidad de almacenamiento de datos apropiado.
2.- Apertura de Archivos.- En este caso se pretende abrir un archivo ya existente en disco para procesarlo, ya sea cargar o grabar datos en sus
registros, o leer algún registro en especial para mandarlo a una variable de cualquier tipo. No confundir creación con apertura creación es un proceso que solo se ejecuta una sola vez en la vida de un archivo, mientras que apertura siempre se está realizando por los programas especializados en algún proceso. 3.-Cierre de archivos: Es la operación más importante en cualquier programa que maneje archivos o se cierra el archivo como ultima instrucción del programa o se verá el anuncio ABORT,RETRY,FAIL. 4.-Altas en archivo.- En este proceso se carga una clase en memoria con sus datos pertinentes y se graba la clase en el archivo en disco. 5.-Lectura de archivo.- En este proceso, se abre el archivo y se manda el registro de disco, a una clase en memoria para su procesamiento. 6.- Consulta de archivos: En este proceso se pretende desplegar todos los registros del archivo en disco a la pantalla ya sea consola o mejor aún, a una pagina html 7.-Busqueda en archivos: Una de las operaciones más comunes, consiste en que el usuario pide toda la información de algún renglón en disco, proporcionando la información de algún campo, generalmente el campo clave de la clase. 8.- Filtros.- En este proceso el usuario está interesado en algún conjunto de renglones con características comunes (condición), por ejemplo todos los alumnos de “sistemas”, o todos los empleados que ganen más de $500.00 pesos, o todos los clientes que sean de “tijuana”, etc 9.-Modificaciones de registros o archivos: Problema muy común, donde los datos originales ya grabados se tienen que cambiar o actualizar, por ejemplo el nombre no era “juan” es “juana”, o la calificación no es 100 es 20, etc. 10.- Bajas de registros: también muy común este proceso por ejemplo el alumno ya egreso, el cliente huyo, etc.
TEMA 5: GRABACION ARCHIVO SECUENCIAL JAVA
Grabación y lectura son los dos procesos más comunes con archivos en cualquier lenguaje de programación.
Código de grabación:
Prog22.java
import java.lang.*;
import java.io.*;
public class prog22 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataOutputStream archivo = null;
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre=new String("");
int edad=0;
// creando objeto teclado
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
// abriendo archivo, capturando y grabando datos
try {
//* Creando y grabando a un archivo, esta larga la instrucción*/
archivo = new DataOutputStream( new
FileOutputStream("c:\\pfacil\\archivo1.dat",true) );
System.out.println("dame clave: ");
clave = Integer.parseInt(teclado.readLine());
System.out.println("dame nombre: ");
nombre=teclado.readLine();
System.out.println("dame edad: ");
edad = Integer.parseInt(teclado.readLine());
//grabando al archivo
archivo.writeInt(clave);
archivo.writeUTF(nombre);
archivo.writeInt(edad);
archivo.close();
}
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
} // cierra main
} // cierra clase
Corrida:
Se usa una clase llamada FileOutputStream, especializada en archivos con muchos métodos y constructores para crear, manipular y procesar archivos el constructor usado solo lleva dos parámetros, el primero todo la ruta o path a donde quedara el archivo(cuidado con no poner la doble diagonal \\) y el segundo parámetro es la palabra “true”, esto es para que el archivo se abra en modo llamado “APPEND”, es decir que cada nuevo registro se vaya escribiendo al final del archivo, si no se pone este parámetro(true), un nuevo registro se sobrescribiría sobre el registro anterior.
Sin embargo en el programa no se uso solo FILEOUTPUSTREAM ( solo para crear el archivo), también se usa DATAOUTPUTSTREAM, esta segunda clase es derivada de la anterior y comparte muchos de sus métodos, la diferencia es que fileoutputstream está especializada en grabar y leer bytes, mientras que dataoutputstream está especializada en grabar y leer datos formateados, observar que los métodos que uso el objeto archivo para grabar o almacenar datos se especializan en algún tipo de dato en especial, sus otros métodos son:
Method Summary
“void” flush”()” Flushes this data output stream.
“int” size”()” Returns the current value of the counter “written”, the number of bytes written to this data output stream so far.
“void” write”(byte[] b, int off, int len)“ Writes “len” bytes from the specified byte array starting at offset “off” to the underlying output stream.
“void” write”(int b)” Writes the specified byte (the low eight bits of the argument “b”) to the underlying output stream.
“void” writeBoolean”(boolean v)” Writes a “boolean” to the underlying output stream as a 1-byte value.
“void” writeByte”(int v)“ Writes out a “byte” to the underlying output stream as a 1-byte value.
“void” WriteBytes (String s) Writes out the string to the underlying output stream as a sequence of bytes.
“void” writeChar”(int v)” Writes a “char” to the underlying output stream as a 2-byte value, high byte first.
“void” WriteChars (String s) writes a string to the underlying output stream as a sequence of characters.
“void”
writeDouble”(double v)“ Converts the double argument to a “long” using the “doubleToLongBits” method in class “Double”, and then writes that “long” value to the underlying output stream as an 8-byte quantity, high byte first.
“void” writeFloat”(float v)” Converts the float argument to an “int” using the “floatToIntBits” method in class “Float”, and then writes that “int” value to the underlying output stream as a 4-byte quantity, high byte first.
“void” writeInt”(int v)“ Writes an “int” to the underlying output stream as four bytes, high byte first.
“void” writeLong”(long v)“ Writes a “long” to the underlying output stream as eight bytes, high byte first.
“void” writeShort”(int v)“ Writes a “short” to the underlying output stream as two bytes, high byte first.
“void” writeUTF (String str) writes a string to the underlying output stream using UTF-8 encoding in a machine-independent manner.
TABLA TOMADA DEL API DE JAVA Observar que la grabación lleva un try-catch filenotfound e ioexception, que son obligatorios o no compila el programa.
No olvidar cerrar el archivo, con la instrucción archivo.close
TEMA 6: LECTURA ARCHIVO SECUENCIAL
El proceso de lectura de los registros de un archivo secuencial es realmente sencillo, como lo muestra el siguiente código ejemplo;
Prog23.java:
import java.lang.*;
import java.io.*;
public class prog23 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataInputStream archivo = null;
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre=new String("");
int edad=0;
try{
//* abriendo archivo para lectura */
archivo = new DataInputStream( new FileInputStream("c:\\pfacil\\archivo1.dat") );
//leyendo archivo
while (true)
{
clave=archivo.readInt();
System.out.println(clave+" ");
nombre=archivo.readUTF();
System.out.println(nombre+" ");
edad=archivo.readInt();
System.out.println(edad+" ");
System.out.println('\n');
} }
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
// cerrar archivo
archivo.close();
} // cierra main
} // cierra clase
Corrida:
Notas:
Observar en código que ahora se usan FILEINPUTSTREAM Y DATAINPUTSTREAM como clases.
En fileinputstream solo se uso el parámetro de abrir archivo (no el true de append) como ya se menciono estas clases se especializan en archivos secuenciales.
El ciclo de lectura se realiza con un while(true)
los métodos de DATAINPUTSTREAM SON:
Method Summary
“int” read”(byte[] b)“
See the general contract of the “read” method of “DataInput”.
“int” read”(byte[] b, int off, int len)“
See the general contract of the “read” method of “DataInput”.
“boolean” readBoolean”()“
See the general contract of the “readBoolean” method of “DataInput”.
“byte” readByte”()“
See the general contract of the “readByte” method of “DataInput”.
“char” readChar”()“
See the general contract of the “readChar” method of “DataInput”.
“double” readDouble”()“
See the general contract of the “readDouble” method of “DataInput”.
“float” readFloat”()“
See the general contract of the “readFloat” method of “DataInput”.
“void” readFully”(byte[] b)“
See the general contract of the “readFully” method of “DataInput”.
“void” readFully”(byte[] b, int off, int len)“
See the general contract of the “readFully” method of “DataInput”.
“int” readInt”()“
See the general contract of the “readInt” method of “DataInput”.
String
with: BufferedReader d
= new BufferedReader(new InputStreamReader(in)); |
| “long” | readLong”()“ See the general contract of the “readLong” method of “DataInput”. |
“short” readShort”()“
See the general contract of the “readShort” method of “DataInput”.
“int” readUnsignedByte”()“
See the general contract of the “readUnsignedByte” method of “DataInput”.
“int” readUnsignedShort”()“
See the general contract of the “readUnsignedShort” method of “DataInput”.
String readUTF”()“
See the general contract of the “readUTF” method of “DataInput”.
“static”
String
readUTF”(“DataInput “in)“
Reads from the stream “in” a representation of a Unicode character string encoded in Java
modified UTF-8 format; this string of characters is then returned as a “String”.
“int” skipBytes”(int n)“
See the general contract of the “skipBytes” method of “DataInput”.
TEMA 7: JAVA BUSQUEDA ARCHIVOS SECUENCIALES
Recordar que existe una serie de procesos básicos con archivos el famoso y antiguo ABC (altas, bajas, consultas y modificaciones) con ellos.
Actualmente estos procesos o similares a ellos se llaman insertar, eliminar, editar, etc., en las modernas bases de datos pero esto lo analizaremos más adelante.
El primer proceso para un archivo secuencial es agregar una cantidad indefinida de registros al archivo este proceso se resuelve o ejecutando una cantidad indeterminada de veces el programa de grabación ya hecho o incluir un ciclo while en el mismo programa.
Un segundo proceso también común, llamado consulta es desplegar todos los registros del archivo a la vez problema también resuelto en el programa de lectura. El tercer Proceso que “resolvemos” en este tema es la búsqueda de un registro determinado, en este proceso el usuario del programa quiere que se despliegue un y solo un registro de información, proporcionando un dato de búsqueda, generalmente la clave del registro.
La solución es sencilla, solo tenemos que abrir el archivo para lectura, hacer un ciclo while(true) condicionar y solo desplegar el registro cuando se cumpla la condición.
Código prog24.Java:
import java.lang.*;
import java.io.*;
public class prog24 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataInputStream archivo = null;
//variables
int clave=0;
int clavebuscar=0;
String nombre="";
int edad=0;
// capturando clave a buscar
// creando un objeto llamado teclado especializado en capturas
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
// capturando datos
try {
System.out.println("dame Clave a buscar: ");
clavebuscar = Integer.parseInt(teclado.readLine());
} catch(IOException variablerror) {System.out.println("error de captura "); }
//* abriendo archivo para lectura */
try{
archivo = new DataInputStream( new FileInputStream("c:\\pfacil\\archivo1.dat") );
//leyendo archivo
while (true)
{
clave=archivo.readInt();
nombre=archivo.readUTF();
edad=archivo.readInt();
if (clavebuscar==clave){
System.out.println(clave+" ");
System.out.println(nombre+" ");
System.out.println(edad+" ");
System.out.println('\n');}; }; }
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
// cerrar archivo
archivo.close();
} // cierra main
} // cierra clase
Corrida programa java:
TEMA 8: FILTROS o CONDICIONES JAVA
Como su nombre lo indica en este proceso se pretende desplegar todo un conjunto de renglones que cumplan con la condición por ejemplo se pide desplegar todos los alumnos de “sistemas” o todos los empleados que sean de “sinaloa”, etc.
Filtros se usan para obtener información acerca de un subconjunto de renglones de el archivo.
Codigo prog25.Java
import java.lang.*;
import java.io.*;
public class prog25 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataInputStream archivo = null;
//variables
int clave=0;
String nombre="";
int edad=0;
int edadfiltro=0;
// capturando condicion
// creando un objeto llamado teclado especializado en capturas
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
// capturando datos
try {
System.out.print("EDAD >= : ");
edadfiltro = Integer.parseInt(teclado.readLine());
} catch(IOException variablerror) {System.out.println("error de captura "); }
//* abriendo archivo para lectura */
try{
archivo = new DataInputStream( new FileInputStream("c:\\pfacil\\archivo1.dat") );
//leyendo archivo
while (true)
{
clave=archivo.readInt();
nombre=archivo.readUTF();
edad=archivo.readInt();
if (edad >= edadfiltro){
System.out.print(clave+" ");
System.out.print(nombre+" ");
System.out.print(edad+" ");
System.out.print('\n');}; }; }
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
// cerrar archivo
archivo.close();
} // cierra main
} // cierra clase
Corrida filtro:
TEMA 9: BAJA ELIMINACION ARCHIVO SECUENCIAL JAVA
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:
1.- Abrir el archivo original en modo lectura. 2.- Abrir un archivo llamado temporal en modo escritura. 3.- Iniciar un ciclo de lectura del archivo original. 3a.- Dentro del ciclo leer el primer registro. 3b.- Validar el registro si no es eliminable, se escribe al archivo temporal. 3c.- Fin de ciclo (cerrar el ciclo). 4.- Cerrar ambos archivos. 5.- eliminar el archivo original. 6.- renombrar el archivo temporal con el nombre de archivo original. Una segunda técnica, consiste en agregar un campo de estado (status) al registro, tal como se vio en el curso anterior: Sin embargo el proceso de baja se tiene que realizar en un sistema de información, para resolver este problema la respuesta 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 está en alta, una 'b' significa que está 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 está de baja dicho registro.”
TEMA 10: OPERACIONES CON CAMPOS JAVA
Este es también un caso común con los elementos de un archivo, sin embargo es también fácil de resolver.
Solo usar los dos archivos el original y el temporal y antes de grabarse al temporal hacer la operación correspondiente, como lo muestra el siguiente ejemplo.
Prog27.java
import java.lang.*;
import java.io.*;
public class prog27 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataInputStream archivo = null;
DataOutputStream archtemp = null;
//variables
int clave=0;
String nombre="";
int edad=0;
try {
//creando archivo temporal
archtemp = new DataOutputStream( new
FileOutputStream("c:\\pfacil\\temporal.dat",true) );
archivo = new DataInputStream( new FileInputStream("c:\\pfacil\\archivo1.dat") );
//leyendo archivo
while (true)
{
clave=archivo.readInt();
nombre=archivo.readUTF();
edad=archivo.readInt();
// sumando +10 a las edades
edad=edad+10;
//grabando al archivo temporal
archtemp.writeInt(clave);
archtemp.writeUTF(nombre);
archtemp.writeInt(edad); }
} catch(IOException variablerror) { }
try {
// cerrar archivos
archivo.close();
archtemp.close();
// eliminando original renombrando temporal
File file1 = new File("c:\\pfacil\\archivo1.dat");
File file2 = new File("c:\\pfacil\\temporal.dat");
if (file1.exists()) {file1.delete();};
file2.renameTo(file1);
// avisando
System.out.println("EDADES + 10");
} catch(IOException variablerror) {System.out.println("ERROR "); }
} // cierra main
} // cierra clase
corrida:
TEMA 11: EDICION REGISTROS JAVA
Editar registros significa cambiar el contenido de algunos de los campos o columnas por nueva información o para corregir algún error de captura original o para agregar alguna columna que no existía por modificación de la tabla o la base de datos.
La solución es similar a los temas anteriores, es decir se ocupan los dos archivos el original y el temporal y ya sea que se modifique una sola clave o se modifiquen todos los registros, el ejemplo que se construye va mostrando los registros del archivo y pregunta y modifica o edita el registro pedido.
Prog28.java
import java.lang.*;
import java.io.*;
public class prog28 {
public static void main(String[] args) {
// crear un objeto de tipo archivo
DataInputStream archivo = null;
DataOutputStream archtemp = null;
//variables
int clave=0;
String nombre="";
int edad=0;
char opcion ='n';
// creando objeto teclado
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
try {
//creando archivo temporal
archtemp = new DataOutputStream( new
FileOutputStream("c:\\pfacil\\temporal.dat",true) );
archivo = new DataInputStream( new FileInputStream("c:\\pfacil\\archivo1.dat") );
//leyendo archivo
while (true)
{
clave=archivo.readInt();
System.out.print(clave+" ");
nombre=archivo.readUTF();
System.out.print(nombre+" ");
edad=archivo.readInt();
System.out.print(edad+" ");
System.out.print('\n');
System.out.print("editar s/n :");
opcion=(teclado.readLine()).charAt(0);
if(opcion=='s'){
System.out.print("dame nuevo nombre: ");
nombre=teclado.readLine();
System.out.print("dame nueva edad: ");
edad = Integer.parseInt(teclado.readLine());
};
//grabando al archivo temporal
archtemp.writeInt(clave);
archtemp.writeUTF(nombre);
archtemp.writeInt(edad); }
} catch(IOException variablerror) { }
try {
// cerrar archivos
archivo.close();
archtemp.close();
// eliminando original renombrando temporal
File file1 = new File("c:\\pfacil\\archivo1.dat");
File file2 = new File("c:\\pfacil\\temporal.dat");
if (file1.exists()) {file1.delete();};
file2.renameTo(file1);
// avisando
System.out.println("YA SE EDITO");
} catch(IOException variablerror) {System.out.println("ERROR "); }
} // cierra main
} // cierra clase
corrida:
UNIDAD 6: PROGRAMACION JAVA REGISTROS Y ARCHIVOS DIRECTOS TEMA 1: JAVA INTRODUCCION ARCHIVOS DISCOS
SE DICE QUE UN ARCHIVO ES DE ACCESO U ORGANIZACION DIRECTA CUANDO PARA ACCEDER A UN REGISTRO N CUALESQUIERA NO SE TIENE QUE PASAR POR LOS N-1 REGISTROS ANTERIIORES.
Como se observa de esta definición los archivos directos tienen una gran ventaja (son mucho más rápidos) cuando se comparan con los archivos de acceso u organización secuencial estudiados en la unidad anterior.
Aunque lo anterior no quiere decir que son mejores que los secuenciales, es decir es el propio problema planteado quien exigirá una solución u otra, por ejemplo si se quiere construir un archivo para almacenar los datos de un guestbook, si se construye de manera directa sería muy rápido pero si lo construimos de manera secuencial, se podrán almacenar datos con cantidades de información más adecuados al problema.
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 esta clase contiene muchas propiedades algunas de las cuales se muestran aquí, estas propiedades se estarán usando mucho en esta unidad.
Un archivo de acceso directo permite posicionar el apuntador de interno de registros, a cualquier registro determinado sin necesidad de pasar por todos los registros anteriores, usando las siguientes funciones.
Constructor Summary
RandomAccessFile”(“File “file,” String “mode)“ Creates a random access file stream to read from, and optionally to write to, the file specified by the “File” argument.
RandomAccessFile”(“String “name,” String “mode)“ Creates a random access file stream to read from, and optionally to write to, a file with the specified name.
Method Summary
“void” close”()“ Closes this random access file stream and releases any system resources associated with the stream.
FileDescriptor getFD”()“ Returns the opaque file descriptor object associated with this stream.
“long” getFilePointer”()“ Returns the current offset in this file.
“long” length”()“ Returns the length of this file.
“int” read”()“ Reads a byte of data from this file.
“int” read”(byte[] b)“ Reads up to “b.length” bytes of data from this file into an array of bytes.
“int” read”(byte[] b, int off, int len)“ Reads up to “len” bytes of data from this file into an array of bytes.
“boolean” readBoolean”()“ Reads a “boolean” from this file.
“byte” readByte”()“ Reads a signed eight-bit value from this file.
“char” readChar”()“ Reads a Unicode character from this file.
“double” readDouble”()“ Reads a “double” from this file.
“float” readFloat”()“ Reads a “float” from this file.
“void” readFully”(byte[] b)“ Reads “b.length” bytes from this file into the byte array, starting at the current file pointer.
“void” readFully”(byte[] b, int off, int len)“ Reads exactly “len” bytes from this file into the byte array, starting at the current file pointer.
“int” readInt”()“ Reads a signed 32-bit integer from this file.
String readLine”()“ Reads the next line of text from this file.
“long” readLong”()“ Reads a signed 64-bit integer from this file.
“short” readShort”()“ Reads a signed 16-bit number from this file.
“int” readUnsignedByte”()“ Reads an unsigned eight-bit number from this file.
“int” readUnsignedShort”()“ Reads an unsigned 16-bit number from this file.
String readUTF”()“ Reads in a string from this file.
“void” seek”(long pos)“ Sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs.
“void” setLength”(long newLength)“ Sets the length of this file.
“int” skipBytes”(int n)“ Attempts to skip over “n” bytes of input discarding the skipped bytes.
“void” write”(byte[] b)“ Writes “b.length” bytes from the specified byte array to this file, starting at the current file pointer.
“void” write”(byte[] b, int off, int len)“ Writes “len” bytes from the specified byte array starting at offset “off” to
this file.
“void” write”(int b)“ Writes the specified byte to this file.
“void” writeBoolean”(boolean v)“ Writes a “boolean” to the file as a one-byte value.
“void” writeByte”(int v)“ Writes a “byte” to the file as a one-byte value.
“void” writeBytes”(“String “s)“ Writes the string to the file as a sequence of bytes.
“void” writeChar”(int v)“ Writes a “char” to the file as a two-byte value, high byte first.
“void” writeChars”(“String “s)“ Writes a string to the file as a sequence of characters.
“void”
writeDouble”(double v)“ Converts the double argument to a “long” using the “doubleToLongBits” method in class “Double”, and then writes that “long” value to the file as an eight-byte quantity, high byte first.
“void”
writeFloat”(float v)“ Converts the float argument to an “int” using the “floatToIntBits” method in class “Float”, and then writes that “int” value to the file as a four-byte quantity, high byte first.
“void” writeInt”(int v)“ Writes an “int” to the file as four bytes, high byte first.
“void” writeLong”(long v)“ Writes a “long” to the file as eight bytes, high byte first.
“void” writeShort”(int v)“ Writes a “short” to the file as two bytes, high byte first.
“void” writeUTF”(“String “str)“ Writes a string to the file using UTF-8 encoding in a machine-independent manner.
TEMA 2: CREACION ARCHIVOS DIRECTOS JAVA
En este proceso se pretende solamente crear un archivo director en disco.
Prog29.java
import java.lang.*;
import java.io.*;
public class prog29 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
// abriendo archivo, capturando y grabando datos
try {
//* Creando y grabando a un archivo, esta larga la instrucción*/
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
archivo.close();
}
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
// avisando
System.out.println("ARCHIVO DIRECTO CREADO");
} // cierra main
} // cierra clase
corrida:
Recordar que la estructura que se uso para crear el archivo se deberá usar siempre y con el mismo orden cuando se acceda al archivo con los procesos u operaciones anteriormente mencionados. Observar que es parecido a la creación de archivos secuenciales.
Lo primero que se crea es un objeto de tipo FILE que se usa como parámetro para crear el archivo de tipo RANDOMACCESSFILE.
Respetar las dos diagonales en el path del disco duro donde quedara el archivo directo.
Como segundo paso se crea el archivo con la instrucción:
RandomAccessFile archivo=new RandomAccessFile(arch,”rw”); Observar el doble diagonal () en el parámetro. El primer parámetro o argumento en esta función es la unidad de disco y el nombre del archivo. El segundo parámetro o argumento es llamado modo y es una de los varios modos que podemos usar. “r” —→ Lectura. “w” —→ Escritura. “rw” —> Crea para lectura y escritura y si ya existe, sobrescribe. Cuando se ha finalizado de escribir al archivo se debe cerrar y esto se hace con la instrucción: Archivo.close(); Recordar estudiar todos los métodos de la clase RANDOMACCESFILE. TAREAS PROGRAMACION JAVA Crear archivos directos de alumnos, proveedores, libros, productos, películas.
TEMA 3: GRABACION Y LECTURA DISCO JAVA
Como ya se menciono grabar y lectura de registros o estructuras a renglones o registros de archivos en disco.
Estos dos procesos son los casos más comunes y frecuentes que se pueden realizar con un archivo de disco.
GRABACION DE UNA ESTRUCTURA A UN ARCHIVO EN DISCO Prog30.java
import java.lang.*;
import java.io.*;
public class prog30 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
// creando objeto teclado
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
// abriendo archivo, capturando y grabando datos
try {
//* Creando y grabando a un archivo, esta larga la instrucción*/
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
System.out.println("dame clave: ");
clave = Integer.parseInt(teclado.readLine());
System.out.println("dame nombre: ");
nombre=teclado.readLine();
//dejando string en 25 caracteres
if (nombre.length() < 25)
{ for(int i=nombre.length(); i <25; i++)
nombre=nombre+" ";}
else{ nombre=nombre.substring(0,25); };
System.out.println("dame edad: ");
edad = Integer.parseInt(teclado.readLine());
// grabando al archivo
if (archivo.length()!= 0){archivo.seek( archivo.length() );};
archivo.writeInt(clave);
// y recordar que cada caracter se graba en dos bytes
archivo.writeChars(nombre);
archivo.writeInt(edad);
archivo.close();
}
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
} // cierra main
} // cierra clase
corrida:
Observar que es completamente similar a programa de archivos secuenciales, solo se recomienda que las claves sigan la secuencia 0,1,2,3,4,5….
La primera observación es que se está usando el modo “rw”, reestudiar la clase de modos de apertura.
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 están ajustando a 25 caracteres, si la string es más corta que dicho tamaño se tendrá que ampliar con caracteres en blanco ” ”, si el tamaño es más grande la string se tendrá que recortar con el método substring(), como se muestra en el programa ejemplo. También es importante recordar que java grabara cada caracter de la string usando dos(2) bites en disco, es decir el registro ejemplo quedara grabado en disco en 58 BYTES, 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 usara ampliamente en el resto de los programas de esta unidad.
Las métodos de grabación que se están usando son:
Archivo.writeInt() y archivo.writeChars().
Recordar estudiar todos los métodos de la clase RANDOMACCESSFILE.
LECTURA CONSULTA DESPLIEGUE DE REGISTROS prog31.java
import java.lang.*;
import java.io.*;
public class prog31 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
//recordar que un caracter son dos bytes en archivo
long tregistro=58;
long cregistros=0;
// creando objeto teclado
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
// abriendo archivo, capturando y grabando datos
try {
//* Creando y leyendo archivo, esta larga la instrucción*/
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
//calulando cantidad de registros
cregistros=archivo.length()/tregistro;
for (int r=0; r < cregistros; r++)
{
clave=archivo.readInt();
//leyendo string
for(int i = 0; i < 25; ++i)
{ nombre += archivo.readChar(); };
edad=archivo.readInt();
//desplegando
System.out.println(clave+" "+nombre+" "+edad);
// limpiar strings o java encadena con la siguiente
nombre="";
};
archivo.close();
}
catch(FileNotFoundException fnfe) { /* Archivo no encontrado */ }
catch (IOException ioe) { /* Error al escribir */ }
} // cierra main
} // cierra clase
corrida:
notas:
Primero se ocupa conocer la cantidad de registros que se encuentran almacenados en disco, para esto primero se ocupan dos variables de tipo long tregistro y cregistros, la cantidad de registros se obtiene con la operación y métodos de la clase RANDOMACCESSFILE siguientes:
cregistros=archivo.length()/tregistro;
Creo que está muy claramente entendible, como se obtuvo la cantidad de registros, ya con esta información se construye un ciclo for (puede ser cualquiera de los ciclos vistos) para empezar a recorrer renglón tras renglón del archivo directo.
La única nota a mencionar es que para leer la string se está usando un ciclo de lectura de 25 caracteres y recordar al final poner la string en nada =”” porque si no en la siguiente lectura se tendrá una string encadenada a la siguiente string.
TEMA 4: BUSQUEDA ARCHIVOS JAVA
En este tema se analiza la búsqueda de un registro o renglón determinado.
En este proceso el usuario del programa quiere que se despliegue un y solo un registro de información proporcionando un dato de búsqueda generalmente la clave del registro.
Recordar que en esta operación se muestra la diferencia fundamental entre archivos secuenciales y archivos directos, es decir aquí se puede accesar directamente un registro n cualquiera.
prog32.java
import java.lang.*;
import java.io.*;
public class prog32 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
long tregistro=58;
// creando objeto teclado y capturando clave
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
try{
System.out.println("dame clave: ");
clave = Integer.parseInt(teclado.readLine());
} catch(IOException ioe) { System.out.println(ioe); }
// abriendo archivo, leyendo
try {
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
archivo.seek(clave * tregistro);
clave=archivo.readInt();
//leyendo string
for(int i = 0; i < 25; ++i)
{ nombre += archivo.readChar(); };
edad=archivo.readInt();
//desplegando
System.out.println(clave+" "+nombre+" "+edad);
// limpiar strings o java encadena con la siguiente
nombre="";
archivo.close();
} catch(FileNotFoundException fnfe) { }
catch (IOException ioe) { }
} // cierra main
} // cierra clase
corrida:
Como se desprende del programa usando archivo.seek() es posible posicionarse en cualquier byte del archivo.
El formato usado seek() es:
Archivo.seek1); Recordar que debemos posicionar el apuntador interno de registros, al principio o inicio del registro que se quiere, por ejemplo en este ejemplo el inicio del registro (1 juan perez 22) se encuentra en el byte 59, pero java inicia una lectura o una escritura en el BYTE ANTERIOR para este caso la lectura debe tener el apuntador interno de registros en el BYTE 58, y si se multiplica la clave 1 por el tamaño de registro 58, adivinar que BYTE SE OBTIENE.
Como va a estar dificil que se le atine a un byte determinado, es por eso que en el programa mejor se deja que sea el propio servidor quien calcule el byte donde empieza un registro determinado con clave * tamaño de registro.
1) long)(clave)* tamañoderegistro
TEMA 5: FILTROS CONDICIONES JAVA
Otro problema similar al anterior es el de filtros o condiciones, es decir en muchas ocasiones es necesario obtener información acerca de un subconjunto de renglones del archivo.
Por ejemplo todos los estudiantes que sean mayores de 17 años, o todos los clientes que sean de Tijuana, etc. a esto le llamamos filtros o condiciones.
También se resuelve de manera similar a los de archivos secuenciales es decir usando un ciclo de lectura de todo el archivo e ir desplegando todos los registros que cumplan la condición.
prog33.java
import java.lang.*;
import java.io.*;
public class prog33 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
long tregistro=58;
long cregistros=0;
int edadtemp=0;
// creando objeto teclado y capturando clave
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
try{
System.out.println("edad mayor que: ");
edadtemp = Integer.parseInt(teclado.readLine());
} catch(IOException ioe) { System.out.println(ioe); }
// abriendo archivo, leyendo
try {
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
//calulando cantidad de registros
cregistros=archivo.length()/tregistro;
for (int r=0; r < cregistros; r++)
{
clave=archivo.readInt();
//leyendo string
for(int i = 0; i < 25; ++i)
{ nombre += archivo.readChar(); };
edad=archivo.readInt();
//desplegando
if (edadtemp <= edad) { System.out.println(clave+" "+nombre+" "+edad);};
// limpiar strings o java encadena con la siguiente
nombre="";
};
archivo.close();
} catch(FileNotFoundException fnfe) { }
catch (IOException ioe) { }
} // cierra main
} // cierra clase
corrida:
Como se observa es un problema y una solución similar al tema anterior de búsquedas.
TEMA 6: BAJAS O ELIMINACIONES JAVA PROGRAMACION
Eliminación o bajas es el proceso por medio del cual algunos registros del archivo son purgados del archivo, existen dos maneras por las cuales se puede realizar ese proceso.
En la primera manera se usan dos archivos, el archivo original y un archivo temporal, el procedimiento o algoritmo es muy sencillo, se lee el registro del archivo original y si no es el registro a eliminar entonces se almacena en el archivo temporal, cuando se termina de procesar todo el archivo original, el archivo temporal solo contendrá todos los registros que no se quisieron eliminar, ya con estos dos archivo se procede a eliminar o borrar usando las instrucciones vistas en el capitulo anterior y se procede a renombrar usando la instrucciones vistas sobre el archivo temporal como nuevo archivo original.
Sin embargo en archivos directos no se puede ni se debe eliminar físicamente registros de los archivos porque recordar que la clave del registro esta enlazada directamente a la posición que dicho registro tiene en disco y no sería muy conveniente estarle cambiando la matricula al alumno cada rato o el número de serie al auto, etc.
Aparte de que con esta manera de eliminar incluso físicamente los registros del archivo es que no hay manera de recuperar esa información posteriormente.
Es por eso que otra técnica común de eliminación es incluir un campo de estado, status o bandera o semáforo en el registro y conforme se va cargando el registro y antes de mandarlo a disco se le agrega a dicho campo el caracter '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.
TEMA 7: OPERACIONES CON CAMPOS JAVA PROGRAMACION
En este tema se analiza la manera de poder realizar operaciones o procesos con los campos de los registros en el archivo directo, lo único importante a considerar es que los campos del registro son en cierta medida igual que variables normales y por tanto se pueden procesar de manera normal como lo muestra el ejemplo.
prog34.java
import java.lang.*;
import java.io.*;
public class prog34 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
long tregistro=58;
long cregistros=0;
// abriendo archivo, leyendo
try {
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
//calulando cantidad de registros
cregistros=archivo.length() /tregistro;
for (int r=0; r < cregistros; r++)
{
// leyendo registro
clave=archivo.readInt();
//leyendo string
for(int i = 0; i < 25; ++i)
{ nombre += archivo.readChar(); };
edad=archivo.readInt();
//sumando edad + 50
edad=edad+50;
//regresando apuntador y regrabando con cambio
archivo.seek( archivo.getFilePointer() -tregistro);
archivo.writeInt(clave);
archivo.writeChars(nombre);
archivo.writeInt(edad);
nombre="";
};
archivo.close();
} catch(FileNotFoundException fnfe) { }
catch (IOException ioe) { }
// avisando
System.out.println("YA TERMINE DE SUMAR");
} // cierra main
} // cierra clase
corrida prog33
como se observa la solución es muy sencilla solo se ocupa:
1.- leer fread() el registro, esto mueve el apuntador al siguiente registro.
2.- modificar registro
3.- regresar a posición anterior con seek()
4.- grabar el registro corregido
y no se ocupan los dos archivos como en el caso secuencial.
TEMA 8: JAVA EDICION MODIFICACION DE REGISTROS
Modificar o editar un registro es uno de los procesos más comunes con archivos en disco, generalmente después de un fuerte proceso de captura de registros, una revisión o consulta general muestra muchos de ellos con errores de captura.
La primera parte del programa es el programa normal de búsqueda que ya se construyo en temas anteriores, pero al desplegar el registro se deberá construir de preferencia un switch() (tarea) que incluya los datos a modificar del registro.
La segunda parte del programa toma los datos, los almacena en el registro en memoria luego se posiciona en el registro en disco a modificar con seek() y se regraban con write().
Prog35.java
import java.lang.*;
import java.io.*;
public class prog35 {
public static void main(String[] args) {
// creando e inicializando los campos del registro
// observar que se debe usar clases numericas apropiadas
int clave=0;
String nombre="";
int edad=0;
long tregistro=58;
// creando objeto teclado y capturando clave
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));
try{
System.out.println("dame clave editar: ");
clave = Integer.parseInt(teclado.readLine());
} catch(IOException ioe) { System.out.println(ioe); }
// abriendo archivo, leyendo
try {
File arch=new File("c:\\ajava\\archivo2.dat");
RandomAccessFile archivo=new RandomAccessFile(arch,"rw");
archivo.seek(clave * tregistro);
clave=archivo.readInt();
//leyendo string
for(int i = 0; i < 25; ++i)
{ nombre += archivo.readChar(); };
edad=archivo.readInt();
//desplegando registro viejo
System.out.println(clave+" "+nombre+" "+edad);
System.out.print("NUEVO NOMBRE: ");
nombre=teclado.readLine();
//dejando string en 25 caracteres
if (nombre.length() < 25)
{ for(int i=nombre.length(); i <25; i++)
nombre=nombre+" ";}
else{ nombre=nombre.substring(0,25); };
System.out.print("NUEVA EDAD: ");
edad = Integer.parseInt(teclado.readLine());
// regresando apuntado y regrabando
archivo.seek( archivo.getFilePointer() -tregistro);
archivo.writeInt(clave);
archivo.writeChars(nombre);
archivo.writeInt(edad);
nombre="";
archivo.close();
} catch(FileNotFoundException fnfe) { }
catch (IOException ioe) { }
} // cierra main
} // cierra clase
Corrida
La única instrucción nueva en este tema es getfilepointer() que se usa para conocer el byte o posición donde se encuentra actualmente el apuntador o puntero interno del archivo, recordar que cuando se leyó el registro en el proceso de búsqueda el apuntador interno se movió hasta el fin del registro por eso cuando se quiere regrabar de nuevo se uso un seek(pointer - tregistro) para regresarse al principio del registro y regrabar.