Sie sind auf Seite 1von 15

2010B

Universidad de
Guadalajara CUCI.
Profesores:
José Sandoval Chávez
Karime Pulido Hernández
Mireya Cacho Ruiz
Norma Alicia Gómez Torres
Oscar Galileo García García

[MANUAL DE TALLER DE
ESTRUCTURA DE ARCHIVOS]

[ALUMNO: ]

[02]
[CONTENIDO]
MODULO 1: La información como un flujo de bits

MODULO 2: Estructura de registros

MODULO 3: Clases para manejo de archivos

MODULO 4: Búsqueda y clasificación de archivos

MODULO 5: Dispersión o hash

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[03]

[MODULO 1]
LA INFORMACIÓN COMO FLUJO DE BITS

[04]

Los tipos de datos básicos y su representación binaria

Java maneja 5 tipos de datos básicos de los cuales se desprenden otros, la siguiente tabla muestra el tipo
de datos, el rango y su peso en bytes.

Tipo Descripción
boolean Tiene dos valores true o false.
Caracteres Unicode de 16 bits Los caracteres alfa-numéricos son los mismos que los ASCII con el bit alto puesto a 0. El intervalo de valores va
char
desde 0 hasta 65535 (valores de 16-bits sin signo).
Int Tamaño 32 bits. El intervalo de valores va desde -2147483648 a 2147483647
float Tamaño 32 bits. Números en coma flotante de simple precisión. Estándar IEEE 754-1985 (de 1.40239846e–45f a 3.40282347e+38f)
Void No tiene tamaño. Este tipo de dato permite definir funciones vacias, es decir que no devuelven algún valor

Es posible cambiar el tipo de dato de un valor realizando una conversión o casting de la siguiente manera:

Variable = (tipo de dato a obtener) valor o variable que se desea convertir.

int i = (int)‟A‟; // esto ofrece un valor entero 65, ya que este es el valor binario de la letra „A‟ (0100 0001)

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[05]
Operadores a nivel de bit y desplazamiento de bit

El lenguaje de programación Java también proporciona operadores que proporcionan operaciones de a nivel
de bit y de desplazamiento de bit en tipos enteros. Los operadores tratados en esta sección son de uso poco
común. Por tanto su cobertura es breve, el objetivo es simplemente hacer constar que estos operadores existen.

El operador complemento a nivel de bit «~» invierte un patrón de bits; se puede aplicar a cualquiera de los tipos
enteros, haciendo de cada «0» un «1» y de cada «1» un «0». Por ejemplo, un byte contiene 8 bits; al aplicar este
operador a un valor cuyo patrón de bits es «00000000» éste se cambiaría a «11111111».

El operador de desplazamiento a la izquierda con signo «<<» desplaza un patrón de bits a la izquierda, y el
operador de desplazamiento a la derecha con signo «>>» desplaza un patrón de bits a la derecha. El patrón de
bits viene dado por el operando de la izquierda y el número de posiciones por el operando de la derecha. El
operador de desplazamiento a la derecha sin signo «>>>» desplaza un cero hacia la posición más a la izquierda,
mientras que la posición más a la izquierda después del «>>» dependa de la extensión de signo.

El operador a nivel de bits & realiza una operación de AND a nivel de bits.

El operador a nivel de bits ^ realiza una operación de OR exclusivo (XOR) a nivel de bits.

El operador a nivel de bits | realiza una operación de OR inclusivo a nivel de bits.

Práctica 1: Realice un programa que represente información utilizando operaciones a nivel de bits.

Preguntas & Respuestas


[06]
1.- Escriba dos tipos de datos que sean similares al int.

______________________________________________________________________________________________________

______________________________________________________________________________________________________

2.- ¿Porqué un String no es un tipo de dato simple?

______________________________________________________________________________________________________

3.- ¿Cuantos símbolos diferentes maneja el código ASCII?

______________________________________________________________________________________________________

4.- Uno de los operadores es utilizado como inversor, ¿Cuál es?

______________________________________________________________________________________________________

5.- ¿Qué operador se utiliza para revisar si una posición de un Byte esta en 0 o 1?

______________________________________________________________________________________________________

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[07]

[MODULO 2]
ESTRUCTURA DE REGISTROS

Procesamiento de archivos de texto [08]


La clase File y Buffered permiten la creación, lectura y escritura de archivos de texto.

En la lectura de ficheros de texto, lo primero que tenemos que hacer es crear un Reader de tipo fichero. Esto es
encapsulado en la clase FileReader. Será esta clase la que utilice el buffer como origen de lectura.

Quedándonos estas simples líneas:

FileReader fr = new FileReader("datos.txt");


BufferedReader bf = new BufferedReader(fr);

O en un formato mas “técnico” podríamos irnos a tener una sola linea de codigo:

BufferedReader bf = new BufferedReader(new FileReader("datos.txt"););

Ahora solo nos queda es ir leyendo del fichero. Para ello utilizaremos los métodos de BufferedReader. Y en
concreto el que nos va dando línea a línea readLine(), La lectura se hará de forma repetitiva hasta que la
lectura de la línea sea nula.

while ((sCadena = bf.readLine())!=null) {


System.out.println(sCadena); }

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[09]
Hay que tener especial cuidado con el manejo de las excepciones. Todo manejo con la librería java.io nos hará
estar expuestos al manejo de la excepción IOException.

Y tampoco podemos olvidar que a la hora de realizar la lectura de un fichero, este, no exista. En ese caso se
lanzará una excepción FileNotFoundException.

Para crear un archivo de texto se utilizan las mismas clases, solo cambia el reader por write.

BufferedWriter sali = new BufferedWriter(new FileWriter("salida.txt"););

Ahora solo nos queda es escribir unos textos dentro del archivo. Para ello utilizaremos los métodos de
BufferedWriter. Y en concreto el que nos va a permitir escribir una línea write().

sali.write(“HOLA DENTRO DEL ARCHIVO…”);

sali.write(„\r‟); sali.write(„\n‟); // introduce un <enter> para obtener un cambio de renglón.

Práctica 2: Realice un programa que procese un archivo de texto, recuerda estudiar la clase String.

[10]
Estructura de registros:

Un campo corresponde con un componente básico de información, muchas veces se relaciona con un atributo
de un objeto, mientras que un registro corresponde con una colección de campos que pueden ser del mismo o
de diferentes tipos, este suele asociarse con un objeto.

Se proponen seis formas de estructurar un archivo de registros y campos.

1 Registro de longitud fija

a) Campos de longitud fija, registros de longitud fija


b) Campos de longitud variable, registros de longitud fija
c) Conteo de número fijo de campos

2 Registros de longitud variable

Colocar un indicador de longitud al comienzo de cada registro en algún formato.

3 Guardar en un segundo archivo la dirección de comienzo de cada registro

4 Utilizar un separador de registro

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
Ejemplo para los registros:
[11]
Nombre: ANA Apellidos: ROSALES MENDEZ Edad: 23 Localidad: OCOTLAN

1a) ANA------------ROSALES MENDEZ------23OCOTLAN--------


< 15 >< 20 ><2>< 15 >
1b) ANA|ROSALES MENDEZ|23|OCOTLAN|---------------------
< 52 >
1c) ANA|ROSALES MENDEZ|23|OCOTLAN|
< 4 campos por registro >
2 30|ANA|ROSALES MENDEZ|23|OCOTLAN|
// al comienzo se coloca la longitud de la cadena, en este caso 30
3 ANA|ROSALES MENDEZ|23|OCOTLAN|
// el archivo de datos contiene los registros en el formato c1|c2|c2|c1|c2|c3| ….
0,30,65,…
// el segundo archivo contiene las direcciones de comienzo de cada registro en el archivo de datos.
4 ANA|ROSALES MENDEZ|23|OCOTLAN|@...

Práctica 3: Realice los programas que tomen n registros y los representen en cada una de las 6 estructuras.

[12]
Preguntas & Respuestas

1.- ¿Que es un archivo de texto?

______________________________________________________________________________________________________

______________________________________________________________________________________________________

2.- Porqué se utilizo la clase Buffered para la lectura y escritura de archivos de texto

______________________________________________________________________________________________________

3.- ¿Qué clase de la biblioteca java.io es necesaria para el esquema 3?

______________________________________________________________________________________________________

4.- ¿Dónde está la longitud fija en el esquema 1 c)?

______________________________________________________________________________________________________

5.- ¿Siempre debe utilizarse la “@” como terminador de registro en el esquema 4?

______________________________________________________________________________________________________

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[13]

[MODULO 3]
CLASES PARA MANEJO DE ARCHIVOS

Paquete java.io [14]


En el paquete java.io existen varias clases de las cuales podemos crear instancias de clases para tratar todo tipo
de ficheros.

Sólo vamos a tratar las tres principales:

 FileOutputStream: Fichero de salida de texto. Representa ficheros de texto para escritura a los que se
accede de forma secuencial.

 FileInputStream: Fichero de entrada de texto. Representa ficheros de texto de sólo lectura a los que se
accede de forma secuencial.

 RandomAccessFile: Fichero de entrada o salida binario con acceso aleatorio. Es la base para crear los
objetos de tipo fichero de acceso aleatorio. Estos ficheros permiten multitud de operaciones; saltar hacia
delante y hacia atrás para leer la información que necesitemos en cada momento, e incluso leer o
escribir partes del fichero sin necesidad de cerrarlo y volverlo a abrir en un modo distinto.

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[15]

Para tratar con un fichero siempre hay que actuar de la misma manera:

1. Se abre el fichero.

Para ello hay que crear un objeto de la clase correspondiente al tipo de fichero que vamos a manejar, y el tipo
de acceso que vamos a utilizar:

TipoDeFichero obj = new TipoDeFichero( ruta );

Donde ruta es la ruta de disco en que se encuentra el fichero o un descriptor de fichero válido.

Este formato es válido, excepto para los objetos de la clase RandomAccessFile (acceso aleatorio), para los que
se ha de instanciar de la siguiente forma:

RandomAccessFile obj = new RandomAccessFile( ruta, modo );

Donde modo es una cadena de texto que indica el modo en que se desea abrir el fichero; "r" para sólo lectura o
"rw" para lectura y escritura.

2. Se utiliza el fichero.

[16]

Para ello cada clase presenta diferentes métodos de acceso para escribir o leer en el fichero.

3. Gestión de excepciones (opcional, pero recomendada)

Se puede observar que todos los métodos que utilicen clases de este paquete deben tener en su definición una
cláusula throws IOException. Los métodos de estas clases pueden lanzar excepciones de esta clase (o sus hijas)
en el transcurso de su ejecución, y dichas excepciones deben de ser capturadas y debidamente gestionadas
para evitar problemas. se destruye el objeto.

Para cerrar un fichero lo que hay que hacer es destruir el objeto. Esto se puede realizar de dos formas, dejando
que sea el recolector de basura de Java el que lo destruya cuando no lo necesite (no se recomienda) o
destruyendo el objeto explícitamente mediante el uso del procedimiento close() del objeto:

obj.close()

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
La clase FileOutputStream [17]
Mediante los objetos de esta clase escribimos en ficheros de texto de forma secuencial.

Presenta el método write() para la escritura en el fichero. Presenta varios formatos:

 int write( int c ): Escribe el carácter en el fichero.


 int write( byte a[] ): Escribe el contenido del vector en el fichero.
 int write( byte a[], int off, int len ): Escribe len caracteres del vector a en el fichero, comenzando desde la
posición off.

La clase FileInputStream

Mediante los objetos de esta clase leemos de ficheros de texto de forma secuencial.

Presenta el método read() para la lectura del fichero. Este método se puede invocar de varias formas.

 int read(): Devuelve el siguiente carácter del fichero.


 int read( byte a[] ): Llena el vector a con los caracteres leídos del fichero. Devuelve la longitud del vector
que se ha llenado si se realizó con éxito o –1 si no había suficientes caracteres en el fichero para llenar el
vector.
 int read( byte a[], int off, int len ): Lee len caracteres del fichero, insertándolos en el vector a.

Todos ellos devuelven -1 si se ha llegado al final del fichero (momento de cerrarle).

[18]
La clase RandomAccessFile

Mediante los objetos de esta clase utilizamos ficheros binarios mediante un acceso aleatorio, tanto para lectura
como para escritura. En estos ficheros hay un índice que nos dice en qué posición del fichero nos encontramos,
y con el que se puede trabajar para posicionarse en el fichero.

Métodos de desplazamiento

Cuenta con una serie de funciones para realizar el desplazamiento del puntero del fichero. Hay que tener en
cuenta que cualquier lectura o escritura de datos se realizará a partir de la posición actual del puntero del
fichero.

 long getFilePointer();Devuelve la posición actual del puntero del fichero.


 void seek( long l ); Coloca el puntero del fichero en la posición indicada por l. Un fichero siempre
empieza en la posición 0.
 int skipBytes( int n ); Intenta saltar n bytes desde la posición actual.
 long length(); Devuelve la longitud del fichero.
 void setLength( long l); Establece a l el tamaño de este fichero.
 FileDescriptor getFD(); Devuelve el descriptor de este fichero.

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[19]
Métodos de escritura

La escritura del fichero se realiza con una función que depende el tipo de datos que se desee escribir.

 void write( byte b[], int ini, int len ); Escribe len caracteres del vector b.
 void write( int i ); Escribe la parte baja de i (un byte) en el flujo.
 void writeBoolean( boolean b ); Escribe el boolean b como un byte.
 void writeByte( int i ); Escribe i como un byte.
 void writeBytes( String s ); Escribe la cadena s tratada como bytes, no caracteres.
 void writeChar( int i ); Escribe i como 1 byte.
 void writeChars( String s ); Escribe la cadena s.
 void writeDouble( double d ); Convierte d a long y le escribe como 8 bytes.
 void writeFloat( float f ); Convierte f a entero y le escribe como 4 bytes.
 void writeInt( int i ); Escribe i como 4 bytes.
 void writeLong( long v ); Escribe v como 8 bytes.
 void writeShort( int i ); Escribe i como 2 bytes.
 void writeUTF( String s ); Escribe la cadena s utilizando la codificación UTF-8.

Los métodos que escriben números de más de un byte escriben el primero su parte alta.

Métodos de lectura
[20]
La lectura del fichero se realiza con una función que depende del tipo de datos que queremos leer.

 boolean readBoolean(); Lee un byte y devuelve false si vale 0 o true sino.


 byte readByte(); Lee y devuelve un byte.
 char readChar(); Lee y devuelve un caracter.
 double readDouble(); Lee 8 bytes, y devuelve un double.
 float readFloat(); Lee 4 bytes, y devuelve un float.
 void readFully( byte b[] ); Lee bytes del fichero y los almacena en un vector b.
 void readFully( byte b[], int ini, int len ); Lee len bytes del fichero y los almacena en un vector b.
 int readInt(); Lee 4 bytes, y devuelve un int.
 long readLong(); Lee 8 bytes, y devuelve un long.
 short readShort(); Lee 2 bytes, y devuelve un short.
 int readUnsignedByte(); Lee 1 byte, y devuelve un valor de 0 a 255.
 int readUnsignedShort(); Lee 2 bytes, y devuelve un valor de 0 a 65535.
 String readUTF(); Lee una cadena codificada con el formato UTF-8.
 int skipBytes(int n); Salta n bytes del fichero.

Si no es posible la lectura devuelven –1.

Práctica 4: Utilice la clase RandomAccessFile para realizar índices (llave+dirección)

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[21]
Preguntas & Respuestas

1.- ¿Que clase permite el acceso a los datos de forma aleatoria?

______________________________________________________________________________________________________

______________________________________________________________________________________________________

2.- ¿Qué clase permite la lectura de textos en forma secuencial?

______________________________________________________________________________________________________

3.- ¿Cuáles son los parámetros del constructor de RandomAccessFile?

______________________________________________________________________________________________________

4.- Clase y método que permite la lectura y escritura de valores de tipo long.

______________________________________________________________________________________________________

5.- Método que permite direccionar el puntero de archivo a cualquier dirección

______________________________________________________________________________________________________

[22]

[MODULO 4]
BUSQUEDA Y CLASIFICACIÓN DE ARCHIVOS

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[23]
Búsqueda binaria en java

Implementación del algoritmo de búsqueda binaria de manera no recursiva en Java.

Recordar que para que funcione correctamente los valores del arreglo deben estar ordenados.

public static int buscar( int [] arreglo, int dato)


{
int inicio = 0; int fin = arreglo.length - 1; int pos;
while (inicio <= fin)
{ pos = (inicio+fin) / 2;
if ( arreglo[pos] == dato ) return pos;
else
if ( arreglo[pos] < dato ) { inicio = pos+1; }
else { fin = pos-1; }
}
return -1;
}
}

Inserción binaria en java [24]


Implementación del algoritmo de inserción binaria de manera no recursiva en Java.

insbinaria(int A[],int N)
{ int aux,izq,der,m=0,j;
for (int i=1;i<N;i++)
{
aux=A[i]; izq=0; der=i-1;
while(izq<=der)
{ m=(int)((izq+der)/2); if (aux<=A[m]) der=m-1; else izq=m+1; } // fin del while (izq<=der)
j=i-1;
while(j>=izq){ A[j+1]=A[j]; j=j-1; }
A[izq]=aux;
System.out.println("PASADA "+i);
for (int k=0; k<N; k++) System.out.print(A[k]+",");
System.out.println();
} // fin del for (int i=1;i<N;i++)

Práctica 5: Realice los índices y búsquedas utilizando búsqueda e inserción binaria.

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[25]

Preguntas & Respuestas

1.- El método de búsqueda binaria termina cuando:

______________________________________________________________________________________________________

______________________________________________________________________________________________________

2.- ¿Cuál es el requisito para el arreglo en la búsqueda binaria?

______________________________________________________________________________________________________

3.- ¿La inserción binaria en que parte del arreglo va dejando los elementos ordenados?

______________________________________________________________________________________________________

4.- ¿Cuale es el propósito de la variable m y pos en ambos algoritmos?

______________________________________________________________________________________________________

5.- ¿Por qué es necesaria la palabra int en la expresión: “ m=(int)((izq+der)/2)” ?

______________________________________________________________________________________________________

[26]

[MODULO 5]
DISPERSIÓN O HASH

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
Función de dispersión
[27]
El hashing o dispersión consta de datos de entrada, una función hash y una salida. Esta función calcula un
código específico para un dato de entrada (como puede ser un nombre, por ejemplo). El valor calculado
puede parecer aleatorio, pero no lo es, ya que las operaciones para computar la salida son siempre las mismas.
La función hash asocia siempre la misma salida para una entrada determinada. Por ejemplo:

hash(“Martín”) = 5432

luego, a los 3 días calculamos hash(“Martín”) nuevamente

hash(“Martín”) = 5432

y el valor computado es el mismo.

La salida de la función hash es siempre un número, este número depende exclusivamente de la entrada porque
las operaciones se realizan sobre estos. Pero la pregunta que nos hacemos es ¿para qué queremos asignarle un
código a un dato de entrada (como ser un nombre)? La respuesta es que este número lo podemos usar para
almacenar ese dato en la posición indicada.

Ejemplo: hash(“Pedro”) = 1234

Entonces vamos a almacenar en la posición 1234 la cadena “Pedro”, además de sus datos personales, por
ejemplo. Cuando se quiera buscar “Pedro” no hace falta recorrer todo el archivo. Calculamos la función hash a
este nombre y accedemos a la posición del arreglo que nos indica la salida de la función.

Algoritmo simple de dispersión


[28]
Existe un algoritmo bastante simple que consta de tres pasos:

1 Representar la llave en forma numérica


2 Desglozar y sumar
3 Dividir entre un numero primo y usar el residuo como dirección

Ejemplo:

Se tiene el registro cuya llave es “LOPEZ < 7 espacios >” y se tienen direcciones de 0 a 99

76 79 80 69 90 32 32 32 32 32 32 32
Paso 1: L O P E Z < 7 espacios >

Paso 2: ((7679+8069)%20000) = 15748


((15748+9032) %20000)= 4780
(( 4780+3232) %20000)= 8012
(( 8012+3232) %20000)= 11244
((11244+3232) %20000)= 14476

Paso 3: 14476 % 101 = 33 // se tomo 101 ya que es el numero primo más cercano a la derecha de 100!

Por dispersión dos llaves pueden ser enviadas a la misma dirección, por lo que ocurren colisiones.

Práctica 6: Aplique la dispersión a un archivo de n registros y visualice las colisiones que se producen.

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García
[29]

Preguntas & Respuestas

1.- ¿Que es una función de dispersión?:

______________________________________________________________________________________________________

______________________________________________________________________________________________________

2.- ¿Qué produce una función de dispersión?

______________________________________________________________________________________________________

3.- ¿Cuántos pasos tiene el método simple de dispersión?

______________________________________________________________________________________________________

4.- ¿Por qué se aplica modulo 20000 a las sumas intermedias en el segundo paso?

______________________________________________________________________________________________________

5.- ¿Por qué usar el residuo de una división entre un número primo?

______________________________________________________________________________________________________

[COMENTARIOS]
_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

_______________________________________________________________

José Sandoval Chávez, Karime Pulido Hernández, Mireya Cacho Ruiz, Norma Alicia Gómez Torres, Oscar Galileo García García

Das könnte Ihnen auch gefallen