Hola a todos, hoy os dejo una serie de ejercicios de Java para practicar todo aquello que hemos explicado en anteriores posts, haciendo hincapié en los ficheros en Java, incluyendo la serialización de objetos
Todos los ejercicios que proponemos están resueltos en este mismo post, intenta hacerlo por ti mismo y si te quedas atascado puedes mirar la solución. Recuerda, que no tiene por que estar igual tu solución con la del post, el objetivo es que aprendas no que me copies la solución.
Crea un proyecto en Java por ejercicio. Colocare en las soluciones algunos comentarios para que sean más fácilmente entendible.
Te recomiendo que uses mensajes de trazas, donde te sean necesarios. Si tienes problemas también puedes usar el depurador.
Aquí tienes todos los posts relacionados con Java:
Curso Java
También incluyo los posts relacionados con eclipse.
Si tienes alguna duda, recuerda que puedes consultarnos escribiendo un comentario en este post o enviándonos un e-mail a administrador@discoduroderoer.es
–Ficheros de texto
1) Crea un fichero de texto con el nombre y contenido que tu quieras. Ahora crea una aplicación que lea este fichero de texto carácter a carácter y muestre su contenido por pantalla sin espacios. Por ejemplo, si un fichero tiene el siguiente texto «Esto es una prueba», deberá mostrar «Estoesunaprueba».
Captura las excepciones que veas necesario.
Spoiler Inside |
SelectShow> |
import java.io.FileReader;
import java.io.IOException;
public class Ejercicio1App {
public static void main(String[] args) {
final String nomFichero="D:\\pruebas.txt";
try(FileReader fr=new FileReader (nomFichero)){
int valor=fr.read();
while(valor!=-1){
//Si el caracter es un espacio no lo escribe
if(valor!=32){
System.out.print((char)valor);
}
valor=fr.read();
}
}catch(IOException e){
System.out.println("Problemas con el E/S "+e);
}
}
}
|
2) Crea una aplicación donde pidamos la ruta de un fichero por teclado y un texto que queramos a escribir en el fichero. Deberás mostrar por pantalla el mismo texto pero variando entre mayúsculas y minúsculas, es decir, si escribo «Bienvenido» deberá devolver «bIENVENIDO». Si se escribe cualquier otro carácter, se quedara tal y como se escribió.
Deberás crear un método para escribir en el fichero el texto introducido y otro para mostrar el contenido en mayúsculas.
IMPORTANTE: cuando pidas por teclado una ruta con JOptionPane, no es necesario que insertes caracteres de escape.
Spoiler Inside |
SelectShow> |
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JOptionPane;
public class Ejercicio2App {
public static void main(String[] args) {
String ruta=JOptionPane.showInputDialog("Introduce la ruta del fichero");
String texto=JOptionPane.showInputDialog("Introduce el texto que quieras escribir en el fichero");
escribirFichero(ruta, texto);
mostrarFicheroMay(ruta);
}
public static void escribirFichero(String nomFich, String texto){
try(FileWriter fw=new FileWriter(nomFich);){
//Escribimos el texto en el fichero
fw.write(texto);
}catch(IOException e){
System.out.println("Problemas en la escritura E/S "+e);
}
}
public static void mostrarFicheroMay(String nomFich){
try(FileReader fr=new FileReader (nomFich)){
int valor=fr.read();
while(valor!=-1){
//Solo cambiara el caracter si es una minuscula o una mayuscula
char caracter=(char)valor;
if(caracter>=97 && caracter<=122){
caracter-=32;
}else if(caracter>=65 && caracter<=90){
caracter+=32;
}
System.out.print(caracter);
valor=fr.read();
}
}catch(IOException e){
System.out.println("Problema con la E/S "+e);
}
}
}
|
3) Crea una aplicación que pida la ruta de dos ficheros de texto y de una ruta de destino (solo la ruta, sin fichero al final). Debes copiar el contenido de los dos ficheros en uno, este tendrá el nombre de los dos ficheros separados por un guion bajo, este se guardara en la ruta donde le hayamos indicado por teclado.
Para unir los ficheros en uno, crea un método donde le pases como parámetro todas las rutas. En este método, aparte de copiar debe comprobar que si existe el fichero de destino, nos muestre un mensaje informándonos de si queremos sobrescribir el fichero. Te recomiendo usar la clase File y JOptionPane.
Por ejemplo, si tengo un fichero A.txt con «ABC» como contenido, un fichero B.txt con «DEF» y una ruta de destino D:\, el resultado sera un fichero llamado A_B.txt en la ruta D:\ con el contenido «ABCDEF».
Puedes crear submétodos para realizar la copia de ficheros, piensa también como podrias optimizar esta copia, si los ficheros tuvieran mucho contenido.
Recuerda que debes controlar las excepciones que puedan aparecer. En caso de error, mostrar una ventana de dialogo con información del error.
Spoiler Inside |
SelectShow> |
import java.io.*;
import javax.swing.JOptionPane;
public class Ejercicio3App {
public static void main(String[] args) {
//Introducimos los datos
String rutaFichero1=JOptionPane.showInputDialog("Indica la ruta del primer fichero");
String rutaFichero2=JOptionPane.showInputDialog("Indica la ruta del segundo fichero");
String rutaDestino=JOptionPane.showInputDialog("Indica la ruta donde quieres guardarlo");
//Creamos dos objetos File para que nos sea mas sencillo manejarlos
File fichero1=new File(rutaFichero1);
File fichero2=new File(rutaFichero2);
//Troceamos el el nombre del primer fichero para que se quede sin extension
String primerFichero=fichero1.getName().substring(0, fichero1.getName().length()-4);
//Crear el nombre de salida del fichero
String nombreFicheroFinal=primerFichero+"_"+fichero2.getName();
rutaDestino+=nombreFicheroFinal;
File destino=new File(rutaDestino);
UneFicheros(fichero1, fichero2, destino);
}
public static void UneFicheros (File fich1, File fich2, File destino){
try (BufferedReader br=new BufferedReader(new FileReader(fich1));
BufferedReader br2=new BufferedReader(new FileReader(fich2))){
int eleccion=-1;
if(destino.exists()){
eleccion=JOptionPane.showConfirmDialog(null, "El fichero ya existe, ¿Quieres sobrescribir el fichero "+destino.getName()+"?",
"Sobrescribir",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
}
if(eleccion!=JOptionPane.CANCEL_OPTION){
/*
* Lo creamos aquí, ya que si lo hacemos arriba
* siempre existira porque se crea al abrir el Stream
*/
BufferedWriter bw=new BufferedWriter(new FileWriter(destino));
//Copiamos el contenido al fichero destino
copiar(bw, br);
copiar(bw, br2);
}
}catch(IOException e){
JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
private static void copiar(BufferedWriter bw, BufferedReader br) throws IOException{
String linea=br.readLine();
while(linea!=null){
bw.write(linea);
linea=br.readLine();
}
}
}
|
–Ficheros binarios
4) Crea una aplicación que copie un fichero binario a otra localización. En lugar de leer y escribir byte a byte, crea un array de bytes con el tamaño del fichero de origen (utiliza el método available()), copia el contenido del fichero a este array y escribe a partir de este array.
Recuerda que debes controlar las excepciones que puedan aparecer. En caso de error, mostrar una ventana de dialogo con información del error.
Spoiler Inside |
SelectShow> |
import java.io.*;
import javax.swing.JOptionPane;
public class Ejercicio4App {
public static void main(String[] args) {
//Pedimos las rutas
String origen=JOptionPane.showInputDialog("Escribe la ruta del origen");
String destino=JOptionPane.showInputDialog("Escribe la ruta del destino");
copiaFicheros(origen, destino);
}
public static void copiaFicheros (String origen, String destino){
try(FileInputStream fis=new FileInputStream(origen);
FileOutputStream fos=new FileOutputStream(destino)){
//Creamos un array de bytes con el tamaño del fichero de origen
byte byteA[]=new byte[fis.available()];
//Copia todos los bytes del fichero al array
fis.read(byteA);
//Escribe todos los bytes en el fichero de destino
fos.write(byteA);
}catch(IOException e){
JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
}
|
5) Crea una aplicación que pida por teclado un número de números aleatorios enteros positivos y la ruta de un fichero. Este fichero contendrá la cantidad de números aleatorios enteros positivos que se ha pedido por teclado.
Escribe los números usando un DataOutputStream y muestra por pantalla estos números leyéndolos con un DataInputStream.
El rango de los números aleatorios estará entre 0 y 100, incluyendo el 100.
Cada vez que ejecutemos la aplicación añadiremos números al fichero sin borrar los anteriores, es decir, si cuando creo el fichero añado 10 números y después añado otros 10 al mismo, en el fichero habrá 20 números que serán mostrados por pantalla.
Spoiler Inside |
SelectShow> |
import java.io.*;
import javax.swing.JOptionPane;
public class Ejercicio5App {
public static void main(String[] args) {
String ruta=JOptionPane.showInputDialog("Escribe la ruta del fichero");
String numeros=JOptionPane.showInputDialog("Escribe el numero de numeros aleatorios");
int numNumerosAleatorios=Integer.parseInt(numeros);
//Abrimos el fichero desde el final
try(DataOutputStream dos=new DataOutputStream (new FileOutputStream (ruta, true));
DataInputStream dis=new DataInputStream(new FileInputStream (ruta))){
escribeFichero(dos, numNumerosAleatorios);
leeFichero(dis);
}catch(EOFException e){
System.out.println("Fin del fichero");
}catch(IOException e){
JOptionPane.showMessageDialog(null, "Error: "+e.getMessage() , "Error", JOptionPane.ERROR_MESSAGE);
}
}
public static void escribeFichero (DataOutputStream dos, int numNumerosAleatorios) throws IOException{
//Escribimos los numeros
for (int i=0;i<numNumerosAleatorios;i++){
int numero=generaNumerosAleatorios();
dos.writeInt(numero);
}
//Guardamos los cambios
dos.flush();
}
public static void leeFichero (DataInputStream dis) throws IOException{
//Leemos los numeros hasta el final del fichero
while(true){
System.out.println(dis.readInt());
}
}
public static int generaNumerosAleatorios(){
int numero=(int)Math.floor(Math.random()*101);
return numero;
}
}
|
6) Crea una aplicación que almacene los datos básicos de un vehículo como la matricula(String), marca (String), tamaño de deposito (double) y modelo (String) en ese orden y de uno en uno usando la clase DataInputStream.
Los datos anteriores datos se pedirán por teclado y se irán añadiendo al fichero (no se sobrescriben los datos) cada vez que ejecutemos la aplicación.
El fichero siempre sera el mismo, en todos los casos.
Muestra todos los datos de cada coche en un cuadro de dialogo, es decir, si tenemos 3 vehículos mostrara 3 cuadros de dialogo con sus respectivos datos. Un ejemplo de salida de información puede ser este:

Spoiler Inside |
SelectShow> |
import javax.swing.JOptionPane;
import java.io.*;
public class Ejercicio6App {
public static void main(String[] args) {
final String RUTA="D:\\vehiculos.ddr";
String matricula=JOptionPane.showInputDialog("Introduce la matricula");
String marca=JOptionPane.showInputDialog("Introduce la marca");
String texto=JOptionPane.showInputDialog("Introduce el tamaño del deposito");
double tamañoDeposito=Double.parseDouble(texto);
String modelo=JOptionPane.showInputDialog("Introduce el modelo");
try(DataOutputStream dos=new DataOutputStream(new FileOutputStream(RUTA,true));
DataInputStream dis=new DataInputStream(new FileInputStream(RUTA))){
introduceDatos(dos, matricula, marca, tamañoDeposito, modelo);
muestraDatos(dis);
}catch(EOFException e){
}catch(IOException e){
JOptionPane.showMessageDialog(null, "Error: "+e.getMessage() , "Error", JOptionPane.ERROR_MESSAGE);
}
}
public static void introduceDatos(DataOutputStream dos,
String matricula,
String marca,
double tamañoDeposito,
String modelo) throws IOException{
dos.writeUTF(matricula);
dos.writeUTF(marca);
dos.writeDouble(tamañoDeposito);
dos.writeUTF(modelo);
}
public static void muestraDatos(DataInputStream dis) throws IOException {
//Cuando se acabe el fichero saltara la excepcion
while(true){
JOptionPane.showMessageDialog(null, "El vehiculo tiene una matricula "+dis.readUTF()+
", su marca es "+dis.readUTF()+", el tamaño del deposito es de "+dis.readDouble()+" " +
"litros y su modelo es "+dis.readUTF());
}
}
}
|
–Serializacion
7) Vamos a realizar el mismo ejercicio pero con serialización, para ello, crea una simple clase Vehiculo con los atributos matricula, marca, tamaño del deposito y modelo, con sus respectivos métodos get y el constructor se invocara con todos los atributos.
El atributo tamañoDeposito no se incluirá en el fichero (aun así debemos pedirlo), debemos indicarlo en la clase (recuerda el uso de transient).
Recuerda que al usar la clase ObjectOutputStream, si vamos a añadir varios objetos en distintas ejecuciones, debemos crear nuestra propia versión de ObjectOutputStream. (Serialización de objetos en Java)
Spoiler Inside |
SelectShow> |
–Clase Vehiculo
import java.io.Serializable;
/**
* Clase Vehiculo
*
* Contiene informacion de un vehiculo
*
* @author DiscoDuroderoer
* @version 1.0
*/
public class Vehiculo implements Serializable{
private static final long serialVersionUID = 7695874286508524707L;
//Atributos
/**
* Matricula del vehiculo
*/
private String matricula;
/**
* Marca del vehiculo
*/
private String marca;
/**
* Tamaño del deposito del vehiculo
* No se transfiere en la serializacion
*/
transient private double tamañoDeposito;
/**
* Modelo del vehiculo
*/
private String modelo;
//Métodos
/**
* Devuelve la matricula
* @return matricula del vehiculo
*/
public String getMatricula() {
return matricula;
}
/**
* Devuelve la marca
* @return marca del vehiculo
*/
public String getMarca() {
return marca;
}
/**
* Devuelve el tamaño del deposito
* @return tamalos del deposito del vehiculo
*/
public double getTamañoDeposito() {
return tamañoDeposito;
}
/**
* Devuelve el modelo
* @return modelo del vehiculo
*/
public String getModelo() {
return modelo;
}
//Constructor
/**
* Constructor con 4 parametros
* @param matricula
* @param marca
* @param tamañoDeposito
* @param modelo
*/
public Vehiculo (String matricula, String marca, double tamañoDeposito, String modelo){
this.matricula=matricula;
this.tamañoDeposito=tamañoDeposito;
this.marca=marca;
this.modelo=modelo;
}
}
–Clase MiObjectOutputStream
import java.io.*;
//Esta clase hereda sus propiedades de ObjectOutputStream
public class MiObjectOutputStream extends ObjectOutputStream {
//Sobrescribimos el método que crea la cabecera
protected void writeStreamHeader() throws IOException
{
// No hacer nada.
}
//Constructores
public MiObjectOutputStream () throws IOException{
super();
}
public MiObjectOutputStream(OutputStream out) throws IOException
{
super(out);
}
}
–Clase ejecutable
import javax.swing.JOptionPane;
import java.io.*;
public class Ejercicio7App {
public static void main(String[] args) {
File fichero=new File("D:\\vehiculos.ddr");
String matricula=JOptionPane.showInputDialog("Introduce la matricula");
String marca=JOptionPane.showInputDialog("Introduce la marca");
String texto=JOptionPane.showInputDialog("Introduce el tamaño del deposito");
double tamañoDeposito=Double.parseDouble(texto);
String modelo=JOptionPane.showInputDialog("Introduce el modelo");
/*
* No creamos los objetos para manejar objetos,
* ya que sino siempre existiria el fichero
*/
try{
Vehiculo vehiculo=new Vehiculo(matricula, marca, tamañoDeposito ,modelo);
//Si el fichero existe, usamos nuestra clase de Object y sino usamos la original
if(fichero.exists()){
MiObjectOutputStream moos=new MiObjectOutputStream(new FileOutputStream(fichero, true));
moos.writeObject(vehiculo);
moos.close();
}else{
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(fichero));
oos.writeObject(vehiculo);
oos.close();
}
//Creamos despues este objeto para asegurarnos que no de un error, en caso de no existir el fichero
ObjectInputStream ois=new ObjectInputStream(new FileInputStream(fichero));
muestraDatos(ois);
}catch(ClassNotFoundException e){
}catch(EOFException e){
System.out.println("fin");
}catch(IOException e){
JOptionPane.showMessageDialog(null, "Error: "+e.getMessage() , "Error", JOptionPane.ERROR_MESSAGE);
}
}
public static void muestraDatos(ObjectInputStream ois) throws IOException, ClassNotFoundException {
//Cuando se acabe el fichero saltara la excepcion EOFException
while(true){
Vehiculo ref=(Vehiculo)ois.readObject();
JOptionPane.showMessageDialog(null, "El vehiculo tiene una matricula "+ref.getMatricula()+
", su marca es "+ref.getMarca()+" y su modelo es "+ref.getModelo());
}
}
}
|
Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.
El ejercicio 3 me ha sacadooo locooo, pero ya se que falla, lo hice primero con mis principiantes conocimientos, funcionaba todo excepto que no supe como hacer para que comprobara si el nuevo fichero ya existia, por lo que lo volvi a hacer copiando el vuestro intentando entenderlo, pero a la hora de ejecutarlo no me escribía en el nuevo fichero el nuevo contenido, todo lo demas bien. Bueno la cosa que ya se que falla, se trata de que falta el bw.flush(); dentro del while(); que nos guarde las posibles líneas. Aprovecho para darte o daros las gracias por esta pagina web, me esta ayudando muchisimo a resolver mis dudas, y lo haceis de manera muy amena. Gracias de veras.
Hola podrías hacer un ejercicio de como leer/escribir en un archivo/fichero como en el ejemplo del auto(marca-modelo-capacidad)
y poder hacer la operaciones básicas
ordenar/agregar/eliminar etc, y que se pueda mostrar la info de los registro ‘n’auto creados en el archivo
He visto algunos ejemplos com la clase RandomAccesFile pero no son muy claros
y algunos utilizan clases extrañas q no encuentra en la documentación de Java(PackingUtils, etc)
buenos probgramas me encantari ayuda xon uno
Hola DiscoDurodeRoer, me alegro de haber encontrado este blog, para los aquellos que recien entramos a este facinante mundo de la programacion el blog es de mucha ayuda, darte gracias por compartir tus conocimientos, y felicitarte por el trabajo que realizaste hasta el momento. (PD «Clases FileInputStream y FileOutputStream para ficheros binarios» esta mal redireccionado).
necesito el codigo para abrir un documento en formato pdf y guardarlo como .txt
Si tengo un array, cómo hago para guardar el contenido del array en un txt y que sea legible ?
En el ejercicio 3 el fichero destino estaba vacío. Falta cerrar el BufferedWriter para que se guarden los cambios