Un fichero binario o de datos está formado por secuencias de bytes. Estos
archivos pueden contener datos de tipo básico (int, float, char, etc) y
objetos.
Para poder leer el contenido de un
fichero binario debemos conocer la
estructura interna del fichero, es decir, debemos saber cómo se han escrito: si hay
enteros, long, etc. y en qué orden están escritos en el fichero. Si no se
conoce su estructura podemos leerlo byte a byte
ESCRIBIR DATOS
EN FICHEROS BINARIOS
Para escribir datos en un fichero
binario utilizaremos las clases Java FileOutputStream y DataOutputStream
derivadas de OutputStream.
FileOutputStream
La clase FileOutputStream permite tener acceso al fichero para
escribir bytes.
Para crear objetos FileOutputStream podemos utilizar los
constructores:
FileOutputStream (String ruta)
FileOutputStream (File objetoFile);
FileOutputStream (String ruta, boolean append)
FileOutputStream (File objetoFile, boolean append)
Si el parámetro append es true
significa que los datos se van a añadir a los existentes.
Si es false los datos existentes
se pierden. Si se utiliza uno de los dos primeros constructores los datos
existentes se pierden.
Los constructores lanzan una excepción
FileNotFoundException si no existe y no se ha podido crear el
fichero.
La clase FileOutputStream
proporciona el método
write() para escribir bytes en el fichero. Este método
lanza una IOException.
DataOutputStream
A partir de un objeto
FileOutputStream se puede crear un objeto DataOutputStream, que proporciona
métodos para escribir
datos de tipo primitivo en el fichero.
Para crear un objeto DataOutputStream se utiliza el constructor:
DataOutputStream(OutputStream nombre);
La clase proporciona métodos writeXxx() donde Xxx es el nombre del
tipo primitivo. Lanzan una IOException
EJEMPLOS JAVA
DE ESCRITURA EN FICHEROS BINARIOS
Ejemplo 1:
Programa que lee enteros por
teclado y los escribe en el fichero datos.dat. La lectura de datos acaba cuando
se introduce -1.
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Binarios1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
FileOutputStream fos = null;
DataOutputStream salida = null;
int n;
try {
fos = new FileOutputStream("/ficheros/datos.dat");
salida = new DataOutputStream(fos);
System.out.print("Introduce número entero. -1 para acabar: ");
n = sc.nextInt();
while (n != -1) {
salida.writeInt(n); //se escribe el número entero en el fichero
System.out.print("Introduce número entero. -1 para acabar: ");
n = sc.nextInt();
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fos != null) {
fos.close();
}
if (salida != null) {
salida.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Ejemplo 2:
Programa Java que crea una matriz
de elementos de tipo double y lee por teclado el valor de sus elementos. A
continuación escribe el contenido de la matriz en un fichero. Al principio del
fichero se escriben dos enteros con los valores del número de filas y columnas
de la matriz.
import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;
public class Binarios2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
FileOutputStream fos = null;
DataOutputStream salida = null;
double[][] matriz;
int filas, columnas, i, j;
do{
System.out.print("Número de filas: ");
filas = sc.nextInt();
}while(filas <= 0);
do{
System.out.print("Número de columnas: ");
columnas = sc.nextInt();
}while(columnas <= 0);
matriz = new double[filas][columnas]; //se crea la matriz
for (i = 0; i < filas; i++) { //lectura de datos por teclado
for (j = 0; j < columnas; j++) {
System.out.print("matriz[" + i + "][" + j + "]: ");
matriz[i][j] = sc.nextDouble();
}
}
try {
//crear el fichero de salida
fos = new FileOutputStream("/ficheros/matriz.dat");
salida = new DataOutputStream(fos);
//escribir el número de filas y columnas en el fichero
salida.writeInt(filas);
salida.writeInt(columnas);
//escribir la matriz en el fichero
for (i = 0; i < filas; i++) {
for (j = 0; j < columnas; j++) {
salida.writeDouble(matriz[i][j]);
}
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fos != null) {
fos.close();
}
if (salida != null) {
salida.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
LECTURA
DE FICHEROS BINARIOS
Para leer de un fichero binario
utilizaremos las clases Java FileInputStream y DataInputStream derivadas de
InputStream.
FileInputStream
La clase FileInputStream permite leer bytes de un fichero.
Para crear objetos FileInputStream podemos utilizar los
constructores:
FileInputStream (String ruta)
FileInputStream (File objetoFile);
Ambos lanzan una excepción
FileNotFoundException si el fichero no existe.
La clase proporciona el método read()
para leer bytes
del fichero.
El método read lanza una excepción
IOException.
DataInputStream
A partir de un objeto FileInputStream
podemos crear un objeto DataInputStream para leer datos de tipo primitivo.
Para crear un objeto DataInputStream se utiliza el constructor:
DataInputStream (InputStream nombre);
La clase proporciona métodos readXxx()
donde Xxx es el nombre del tipo primitivo. Lanzan una excepción IOException.
Cuando un método readXxx() alcanza
el final del fichero lanza una excepción EOFException.
EJEMPLOS JAVA
DE LECTURA DE FICHEROS BINARIOS
Ejemplo 3:
Programa que lee el contenido del fichero creado en el Ejemplo 1. Utilizaremos
un bucle infinito para leer los datos. Cuando se llega al final del fichero se
lanza la excepción EOFException que se utiliza para salir del bucle while.
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Binarios3 {
public static void main(String[] args) {
FileInputStream fis = null;
DataInputStream entrada = null;
int n;
try {
fis = new FileInputStream("/ficheros/datos.dat");
entrada = new DataInputStream(fis);
while (true) {
n = entrada.readInt(); //se lee un entero del fichero
System.out.println(n); //se muestra en pantalla
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (EOFException e) {
System.out.println("Fin de fichero");
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (entrada != null) {
entrada.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Ejemplo 4:
Programa Java que lee el contenido
del fichero creado en el Ejemplo 2 y lo muestra por pantalla.
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Binarios4 {
public static void main(String[] args) {
FileInputStream fis = null;
DataInputStream entrada = null;
int filas, columnas, i, j;
try {
fis = new FileInputStream("/ficheros/matriz.dat");
entrada = new DataInputStream(fis);
filas = entrada.readInt(); //se lee el primer entero del fichero
columnas = entrada.readInt(); //se lee el segundo entero del fichero
for (i = 0; i < filas; i++) {
for (j = 0; j < columnas; j++) { // se leen los double y se muestran por pantalla
System.out.printf("%8.2f", entrada.readDouble());
}
System.out.println();
}
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (EOFException e) {
System.out.println("Fin de fichero");
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
if (fis != null) {
fis.close();
}
if (entrada != null) {
entrada.close();
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
}
Hola muy buenas, hice hace poco un cursillo de JAVA y para no olvidar lo aprendido me estoy ejercitando con estos ejercicios aquí expuestos. He hecho los cuatro de esta página, pero el último me falla? Lo he repasado no no veo diferencias en el código, el problema es que el programa que lee la matriz solo lee ceros, quizás el problema esté en el que los guarda, al ser en un archivo binario no se como comprobarlo.Alguna ayuda ?. Carlos.
ResponderEliminarajaaa, ya encontré el errorrrrrrr.
EliminarNo hice copia y pega, sino que lo escribí a mano y el prg que leía la matriz no leía correctamente, el problema estaba en el prg que grababa la matriz y en concreto cuando se almacena el numero de columnas con la instrucción:
salida.writeInt(columnas);
lo puse
salida.write(columnas);
y así cuando leo las columnas el dato está corrupto.
Carlos me alegro de que hayas encontrado y corregido el error. Así da gusto resolver dudas!!
EliminarEnrique, gracias por pasarte.
EliminarSaludos a todos. guardo de datos de pacientes en un archivo binario (numero de expediente, dni, apellidos, nombres, telefono, direccion y fotografia del paciente), cuando hago la busqueda a traves del numero de expediente solo me muestra el ultimo paciente ingresado y los anteriores no salen, al parecer al guararlos se sobreescriben, aqui les dejo el codigo de guardar y buscar para que me puedan ayudar,
ResponderEliminarprivate void btcGuardarActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Object nombreArchivo = archivo;
System.out.println(nombreArchivo);
try{
ObjectOutputStream fileout = new ObjectOutputStream(new FileOutputStream((String) nombreArchivo));
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fichero,true));
fileout.writeObject(txtNroExpediente.getText());
fileout.writeObject(txtDni.getText());
fileout.writeObject(txtApellidos.getText());
fileout.writeObject(txtNombres.getText());
fileout.writeObject(txtDireccion.getText());
fileout.writeObject(txtTelefono.getText());
fileout.writeObject(lblFoto.getIcon());
JOptionPane.showMessageDialog(null, "Los datos del paciente se guardaron corecttamente...");
if(fileout!=null){
fileout.close();
}
}catch(IOException e){}
desactivarTextFields();
btcGuardar.setEnabled(false);
btcNuevo.setEnabled(true);
btcBuscar.setEnabled(false);
}
private void btcBuscarActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Object nombreArchivo = archivo;
try{
try (ObjectInputStream filein = new ObjectInputStream(new FileInputStream((String) nombreArchivo))){
Object expediente = filein.readObject();
Object dni = filein.readObject();
Object apellidos = filein.readObject();
Object nombres = filein.readObject();
Object direccion = filein.readObject();
Object telefono = filein.readObject();
Object foto = filein.readObject();
if (txtNroExpediente.getText().equals(expediente)){
txtNroExpediente.setText((String) expediente);
txtDni.setText((String) dni);
txtApellidos.setText((String) apellidos);
txtNombres.setText((String) nombres);
txtDireccion.setText((String) direccion);
txtTelefono.setText((String) telefono);
lblFoto.setIcon((Icon) foto);
}
if(filein!=null){
filein.close();
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(JDPacientes.class.getName()).log(Level.SEVERE, null, ex);
}
}catch(IOException e){}
}
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fichero,true)); Es la forma correcta. Si no pones el true entonces se sobreescribe. atte Ramon
ResponderEliminarPrimero, agradecerte por a ver leido y respondido mi problema. agregue lo del true, pero igual sigue reescribiendo, solo cuando el ingreso el ultimo numero de expediente me muestra ese paciente. tienes algun email para enviarte mi proyecto y lo abras y le des una miradita.?
Eliminarclaramente esto es brujería!!!
ResponderEliminarPero si se guarda los datos como arch binario, y yo uso el metodo writeChar('a'), por ejm. Yo abro el archivo y leo exactamente la "a", no debería verse algo en binario o que mas bien no lo pueda leer como cuando con los números si se usa writeInt(14), abre el archivo y se ve ♫. No entiendo eso. Son archivos binarios y el texto se lo puede leer tranquilamente.
ResponderEliminarPobre animal, es binario porque te devuelve el mismo tipo de dato que agregaste ya sea char, int o cualquier wuebada que pongas, a diferencia de los archivos de texto que solo te devuelve String.
EliminarAtt: tu papa .l.
Este comentario ha sido eliminado por el autor.
Eliminarif (fos != null) {
ResponderEliminarif (salida != null) {
¿Esas partes que significan? En las condiciones.
O ¿Como se leen?
SI fos es distinto de null
EliminarSI salida es distinto de null
Es una manera de comprobar que el objeto está inicializado
Este comentario ha sido eliminado por el autor.
ResponderEliminarSe puede hacer uno donde solo busque un nombre o cadena dentro del archivo.dat
ResponderEliminarde lokos
ResponderEliminarHola me podrían ayudar a resolver este ejercicio por favor
ResponderEliminarHacer un programa utilizando los temas de archivos de datos, paquetes y excepciones, que me
permita almacenar los datos de una agenda con los sig.: Nombre, Dirección, Código postal,
ciudad, país y Teléfono. El programa mostrara un menú que me permita: 1) Ingresar datos a la
agenda, 2) Mostrar el nombre, teléfono y dirección, 3) Buscar un teléfono en la agenda y mostrar
el nombre y teléfono, 4) Salir.
Me sale que \ficheros/dato.dat el sistema no puede encontrar la ruta especificada y el programa no me ejecuta que hago?
ResponderEliminar