sábado, 23 de marzo de 2013

Entrada y salida estándar en Java


ESCRITURA DE DATOS EN LA CONSOLA DEL SISTEMA
PrintStream
La clase PrintStream permite dar formato a la salida.
Cuando la aplicación arranca, automáticamente se crea un objeto System.out  que permite establecer comunicación entre la aplicación y el sistema operativo utilizando, para ello, los métodos de formato que proporciona la clase PrintStream:
print: envía cadenas de caracteres a la consola del sistema.
System.out.print (“cadena que se va a mostrar”);
La salida por consola sería:

La salida se muestra toda en la misma línea. Para que la salida del método print genere una nueva línea hay que incluir el carácter de salto de línea (‘\n’):
La salida de esta instrucción sería:

Este mismo resultado se puede obtener con el método println.
El método print se puede usar también para enviar a la consola cualquier tipo de dato:

Salida:

O combinación de datos utilizando el operador + para concatenarlos:
y su salida:

println: funciona igual que print solo que incluye un salto de línea tras la cadena automáticamente.
System.out.println (“cadena que se va a mostrar”);
La salida es la misma que en el caso del print, solo que no es preciso indicar el salto de línea ya que se incluye automáticamente.

printf: permite incluir formato en la salida generada utilizando mascarillas de formato:
System.out.printf (“cadena con mascarillas”, argumentos);
Las mascarillas son especificadores de formato que indican el tipo de dato que se quiere mostrar. Usándolos dentro de una cadena se puede definir el formato completo de la cadena y la colocación de los datos dentro de la misma:

Mascarilla
Tipo de dato que representa
B, b
boolean
H, h
cadena de caracteres en hexadecimal
S, s
cadena de caracteres
C, c
char
d
entero
o
valor numérico en octal
X, x
valor entero en hexadecimal
E, e
real con notación científica
f
coma flotante
G, g
coma flotante
A, a
coma flotante en hexadecimal
T, t
formato de fecha y hora

Las mascarillas hay que usarlas con el operador % y tienen el siguiente formato:
% [índice] [modificadores] [ancho] [numero_decimales] mascarilla

índice: número del argumento que tomará el valor especificado. El primero: 1$, el segundo 2$ y así sucesivamente. La lista de argumentos se incluye en la parte derecha de la función printf.  Si no se indica el numero de argumento las mascarillas se aplican por orden:
En este ejemplo la mascarilla %d hace referencia a un número entero, como no se indica ningún número de argumento se aplicará al primero, la x. La segunda mascarilla representa un número real. Tampoco se indica número de argumento por lo que se aplicará al segundo argumento, la y.
La salida en la consola será la siguiente:

En el siguiente ejemplo se obtiene el mismo resultado pero incluyendo los índices de los argumentos:
Modificadores: Incluyendo un + se mostrará el signo. El signo negativo ( - ) siempre se muestra aunque no se ponga el modificador:
La salida de esta instrucción será la siguiente:

Ancho: Número mínimo de caracteres que se imprimirán. Si el dato los supera no se verá afectado, si no los alcanza se incluirán espacios en blanco por la izquierda hasta completarlos:
La salida en consola:

Numero de decimales: Esto solo se puede aplicar a datos con coma flotante.  Indica el numero de decimales que se quieren imprimir. Hay que escribirlos precedidos por un punto ( . ):
En la salida se puede apreciar que el numero de decimales se ha reducido:

Todos los formatos se pueden combinar entre si para conseguir el resultado deseado:
Su salida será:

Existe otra versión de este método:
System.out.printf (Locale , “cadena con mascarillas”, argumentos);

Locale: Activa las características  regionales de formato para números y fechas según la región lingüística. Este objeto lo explicaré más adelante junto con las fechas.

NOTA: La clase PrintStream se está empezando a reemplazar por la clase PrintWriter, ya que gestiona mejor los caracteres Unicode pero, a pesar de ello, se siguen usando los métodos de formato de la clase PrintStream sin que el compilador los identifique como obsoletos (deprecation).


LECTURA DE DATOS A TRAVÉS DE LA CONSOLA DEL SISTEMA

Hay dos formas de leer datos de teclado en java. La clásica consiste en utilizar las clases InputStreamReader y BufferedReader. La otra forma, más nueva, es usar la clase Scanner.
En ambos casos hay que seguir el paradigma fuente-flujo-filtro.
Fuente: origen de los datos
Flujo: medio para transportar los datos
Filtro: dispositivo de interpretación de los datos

InputSreamReader y BufferedReader
Al igual que el objeto System.out, existe un objeto System.in que se crea automáticamente al iniciarse la aplicación e identifica la consola como periférico de entrada.

En este caso, el objeto System.in será la fuente.

Del flujo de datos se encarga la clase InputStreamReader a la que se le indicará la fuente (System.in) en el momento de la creación del objeto correspondiente:

El flujo servirá como argumento para crear el filtro, un objeto de la clase BufferedReader que será el encargado de recuperar la cadena que introduce el usuario a través del teclado:

La clase BufferedReader proporciona un método readLine que recuperara todo el flujo de información en formato de cadena de caracteres (String):

En el siguiente ejemplo se le solicita al usuario su nombre. El objeto BufferedReader recuperará, con el método readLine,  el flujo de bytes sin formato que se recoge de la consola a través del objeto InputStreamReader. Posteriormente transforma este flujo de información en una cadena de caracteres (String) que se almacena en el objeto nombre. Si se imprime este ultimo objeto con el método println, se podrá ver en la consola el dato que ha introducido el usuario:
Comentar un par de cosas más sobre este código. Para poder usar BufferedReader e InputStreamReader hay que importar el paquete java.io. Por eso se incluyen estas tres líneas al principio del código:

También se pueden reemplazar por esta otra que importaría el paquete completo y no solo las clases que se van a usar:

La segunda línea:

y la instrucción throws del main:
sirven para la gestión de excepciones. Siempre que se utilice el método readLine será necesario realizar esta operación o el programa no compilará.
La gestión de excepciones la trataré en profundidad más adelante.
La salida de este ejemplo sería:


El usuario escribe su nombre:

El programa le saluda:

NOTA: Si se quieren leer datos que no sean String, hay que parsearlos utilizando las clases envoltorio. Como ya dije en el post anterior, las explicaré más adelante.

Scanner
El otro modo de leer datos de teclado es usando la clase Scanner. Es mucho más simple de usar ya que no produce excepciones y la sintaxis es mucho más sencilla.

La fuente de datos sigue siendo System.in, puesto que es el objeto que identifica la consola pero, tanto el flujo como el filtro son cosa de Scanner.


En este caso también hay que importar el paquete java.io:
O solo la clase Scanner:

Scanner tiene el metodo nextLine que realiza la misma función que readLine de la clase BufferedReader.:


La salida de este programa será la misma que en el caso de usar BufferedReader y InputStreamReader.
Scanner, además de permitir leer los datos en formato String, proporciona otros métodos que permiten recuperar la información en otros formatos:
Metodo
Dato
nextByte()
byte
nextShort()
entero corto
nextInt()
entero
nextLong()
entero largo
nextFloat()
punto flotante simple precisión
nextDouble()
punto flotante doble precisión
nextBoolean()
booleano

Se usan igual que readLine pero cambiando el tipo de la variable que almacenará la información que se lee:

No hay comentarios:

Publicar un comentario