2010-04-13 21 views
6

Puedo "arreglar" la excepción a continuación con un ciclo try-catch pero no puedo entender la razón.Java: ¿para qué sirve IOEXceptions en ReadLine() de BufferedReader?

  1. ¿Por qué la parte "in.readLine()" enciende continuamente IOExceptions?
  2. ¿Cuál es realmente el propósito de arrojar tales excepciones, el objetivo probablemente no solo más efectos secundarios?

Código y IOExceptions

$ javac ReadLineTest.java 
ReadLineTest.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown 
    while((s=in.readLine())!=null){ 
        ^
1 error 
$ cat ReadLineTest.java 
import java.io.*; 
import java.util.*; 

public class ReadLineTest { 
public static void main(String[] args) { 
    String s; 
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 
    // WHY IOException here? 
    while((s=in.readLine())!=null){ 
    System.out.println(s); 
    } 
} 
} 
+2

Tutorial de excepciones de Sun: http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html – BalusC

Respuesta

7

La idea básica es que un BufferedReader delegue en un tipo diferente de Reader, por lo que está pasando esa excepción.

Ese tipo diferente de Reader puede leer de algún tipo de recurso externo volátil, por ejemplo, un sistema de archivos en el caso de FileReader. Una lectura del sistema de archivos puede fallar por muchas razones en cualquier momento. (La situación es peor si el lector obtiene sus datos subyacentes de un flujo de red). El archivo podría eliminarse debajo de usted (dependiendo del sistema de archivos y sistema operativo involucrados).

Como no se puede predecir qué sucederá con el código, se obtiene una excepción comprobada: el punto es que la API le dice que debe pensar en el hecho de que esta operación puede no funcionar incluso si no hay nada de malo en tu codigo.

1

IOException es una checked exception. Debes atraparlo o lanzarlo a tu método de llamada. Las excepciones controladas son causadas por actores externos, como un archivo faltante, un disco fallido o cualquier cosa de la que no pueda recuperarse en el código de su programa.

Sin embargo, una excepción no comprobada como ArrayIndexOutofBoundsException es causada por una lógica defectuosa en el programa. Puede subvertirlo utilizando una condición if fuera de su código defectuoso (algo así como si currIndex> array.length). No existe tal disposición en caso de excepción marcada

1

Se emite si ocurre una situación excepcional con la E/S, por ejemplo, la fuente de la transmisión ya no está disponible.

En tales casos, su programa debería ser capaz de recuperarse. Ya sea volviendo a leer la fuente, o utilizando algunos valores predeterminados, o alertando al usuario sobre el problema.

Se lo fuerza a catch, porque es una excepción comprobada, y se supone que usted puede recuperarse de eso.

Por supuesto, tiene la opción de declarar que el menthod actual throws esta excepción a los métodos del que llama, pero tendrá que atraparlo eventualmente (o dejarlo burbujear hasta el método principal, cuando simplemente se imprime en el consola y se detiene la ejecución del programa)

+2

@downvoter - déjame corregir lo que piensas que está mal con esta respuesta. – Bozho

2

BufferedReader.readLine() se declara como potencialmente lanzar una excepción, ver: http://java.sun.com/j2se/1.3/docs/api/java/io/BufferedReader.html#readLine()

o hay que hacer atraparlo, o declarar su principal método como tirar IOException.

Es decir, ya sea hacer esto:

try { 
    while((s=in.readLine()) != null){ 
     System.out.println(s); 
    } 
} catch(IOException e) { 
    // Code to handle the exception. 
} 

O

public static void main(String[] args) throws IOException { ... 
3
  1. No va a "encender continuamente" ellos, que sólo podría tirarlos cada vez que se invoca. En su caso, si arroja algo, significa que algo salió mal con su entrada estándar.
  2. El objetivo es asegurarse de que usted, el programador que utiliza la API, resuelva el problema, ya que en general se supone que es un problema recuperable, aunque en su caso particular, será fatal para todo el programa.
0

El uso de Scanner para leer archivos (u otro tipo de entrada) puede ser extremadamente ineficiente en situaciones de media/gran escala. Si tiene problemas de rendimiento al leer miles o millones de líneas, le recomiendo usar la clase BufferedReader. Un ejemplo del uso de BufferedReader para leer las líneas de System.in se muestra a continuación:

public static void main(String[] args) throws Exception { 

    String line = null; 
    BufferedReader br = new BufferedReader (new InputStreamReader(System.in)); 

    try { 
     /* This is protected code. If an problem occurs here, catch block is triggered */ 
     while ((line = br.readLine()) != null){ 
      System.out.println(line); 
     } 
    } 
    catch (IOException e){ 
     throw new IOException("Problem reading a line",e); 
    } 
} 

IOException se debe utilizar en try/catch bloque por lo que puede ser activado cada vez que el código protegido dentro de try sufre de un comportamiento "excepcional" tal como un error . Java tiene sus propias excepciones que se lanzan cuando ocurre una situación similar. Por ejemplo, ArrayIndexOutOfBoundsException se lanza cuando define una matriz a de tamaño n e intenta acceder a la posición a[n+1] en algún lugar de su código. Como ArrayIndexOutOfBoundsException, hay muchas otras clases de excepciones que puede lanzar y personalizar con sus propios mensajes. El código adecuado para una excepción debe colocarse en la zona protegida en el bloque try. Cuando se produce la excepción en ese bloque, la excepción se manejará en bloque catch con él.

Parece que no es necesario crear declaraciones if/else para anticipar la situación de error y lanzar una excepción para cada caso. Solo necesita asociar posibles situaciones de excepción entre el bloque try y catch. Ver más sobre try/catch blocks es recomendado para una programación segura.