TIPOS DE STREAMS EN JAVA
Publicado el 21 diciembre, 2012 por admin
Las aplicaciones java usan un sistema de streams para leer y escribir información. A ellos se accede desde el
paquete java.io, donde se encuentran varias clases de entrada y salida, que permiten manejar caracteres, bytes, objetos o
datos primitivos.
Loa streams en java son secuencias de información que soportan diferentes tipos de fuentes y destinos como, el teclado, la
consola, ficheros, páginas web. Por tanto, en esta entrada vamos a conocer de manera básica las principales clases
I/O que actúan para gestionar estas operaciones.
Podemos clasificar los streams según el tipo de datos con los que trabajan en:
Streams de bytes
Todas las clases que permiten gestionar entradas y salidas de bytes (8 bits) heredan de las clases abstractasInputStream y
OutputStream. Las del primer tipo son utilizadas para leer, mientras las segundas para escribir. Su uso está orientado al
trabajo con formatos binarios, por ejemplo, archivos de audio y vídeo. Algunas subclases principales son:
InputStream ( lectura )
FileInputStream
FilterInputStream
StringBufferInputStream
ObjectInputStream
BufferedInputStream
DataInputStream
OutputStream ( escritura )
FileOutputStream
FilterOutputStream
ObjectOutputStream
BufferedOutputStream
DataOutputStream
Character Streams
Permiten el flujo de caracteres ( 16 bits ), por tanto, a menudo se usan con archivos de texto. Las diferentes clases
disponibles en java para su manejo heredan de Reader y Writer. Las primeras, como su nombre indica sirven para leer
información y las últimas para escribirla. Algunas de las subclases más importantes son:
Reader ( lectura )
FileReader
FilterReader
BufferedReader
InputStreamReader
Writer ( escritura )
FileWriter
FilterWriter
BufferedWriter
StringWriter
El método close ()
Un stream se cierra cuando ya no es necesaria su utilización. Esto se consigue mediante una llamada al método close (). De
este modo, podemos evitar importantes perdidas de recursos.
Nota. A partir de Java 7 ya no es necesario usar el método close(). El nuevo bloque try ( ) { }catch{ } permite cerrar el
stream de manera automática.
Cambiar de byte a character
También encontramos 2 clases en java.io para cambiar el tipo de stream:
InputStreamReader: lee bytes y los convierte a caracteres.
OutputStreamWriter: pasa de caracteres a bytes.
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 SeleccionarEsconder
12345678910111213141516171819202122
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 SeleccionarEsconder
1234567891011121314151617181920212223
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); } }
24252627282930313233343536373839404142434445464748495051
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 SeleccionarEsconder
123456789101112131415161718
import java.io.*;import javax.swing.JOptionPane;public class Ejercicio5App { 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();
19202122232425262728293031323334353637383940414243444546474849
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){
505152535455565758596061626364656667686970717273
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 SeleccionarEsconder
12345678910111213141516171819202122232425262728293031
import java.io.*;import javax.swing.JOptionPane; public class Ejercicio6App { 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); } }
}
323334
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 SeleccionarEsconder
1234567891011121314151617
import java.io.*;import javax.swing.JOptionPane; public class Ejercicio7App { 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){
18192021222324252627282930313233343536373839404142434445464748
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; }
}
4950515253
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 SeleccionarEsconder
12345678
import javax.swing.JOptionPane;import java.io.*; public class Ejercicio9App { public static void main(String[] args) { final String RUTA="D:\\vehiculos.ddr";
9101112131415161718192021222324252627282930313233343536373839
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 {
4041424344454647484950515253
//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 SeleccionarEsconder
–Clase Vehiculo1234567
import java.io.Serializable; /** * Clase Vehiculo * * Contiene informacion de un vehiculo * * @author DiscoDuroderoer * @version 1.0
891011121314151617181920212223242526272829303132333435363738
*/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; }
39404142434445464748495051525354555657585960616263646566676869
/** * 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;
707172737475767778798081828384858687
}
}
–Clase MiObjectOutputStream
123456789101112
import java.io.*; //Esta clase hereda sus propiedades de ObjectOutputStreampublic class MiObjectOutputStream extends ObjectOutputStream { //Sobrescribimos el método que crea la cabecera protected void writeStreamHeader() throws IOException { // No hacer nada. }
//Constructores
131415161718192021
public MiObjectOutputStream () throws IOException{ super(); } public MiObjectOutputStream(OutputStream out) throws IOException { super(out); }}
–Clase ejecutable
123456789101112131415161718192021
import javax.swing.JOptionPane;import java.io.*; public class Ejercicio10App { 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);
22232425262728293031323334353637383940414243444546474849505152
//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());
5354555657585960
} }
}
Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.
Top Related