Estructura de Datos con Orientación a Objetos 4. Manejo de excepciones y E/S por archivos Cynthia A. Rodrı́guez Villalobos Universidad Autónoma Metropolitana Unidad Azcapotzalco 2011-O Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 1 / 21 Contenido: 1 Manejo de excepciones 2 Entrada y salida por archivos Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 2 / 21 Contenido: 1 Manejo de excepciones 2 Entrada y salida por archivos Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 3 / 21 Manejo de excepciones Introducción El manejo de excepciones permite gestionar los errores en tiempo de ejecución de forma ordenada Se puede llamar a una rutina de manejo de errores cuando se produzca un error Permite la fácil visualización y comprensión del código. Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 4 / 21 Manejo de excepciones Introducción El manejo de excepciones tiene su base en 3 palabras reservadas: 1 Las instrucciones que pueden producir excepciones se incluyen en un bloque try 2 Si se produce una excepción (un error) dentro del bloque try se notifica mediante throw 3 La excepción se captura con catch y se procesa Las excepciones deben capturarse por una sentencia catch que se encuentre inmediatamente después de la sentencia try Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 5 / 21 Manejo de excepciones C++ y Java 1 En C++, el manejo de excepciones fue un anexo Las primeras versiones de C++ no tenan manejo de excepciones Las bibliotecas estndar no utilizan el mecanismo de manejo de excepciones Se utilizan valores de retorno para manejar errores Se puede lanzar cualquier tipo de dato 2 En Java, el manejo de excepciones se consider desde el principio Las bibliotecas utilizan el mecanismo de manejo de excepciones Casi todos los programas en este lenguaje utilizan este mecanismo en lugar de los valores de retorno Sólo se pueden lanzar objetos de subclases de Throwable Incluye la sentencia finally para “limpiar” la pila. Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 6 / 21 Manejo de excepciones Ejemplo: C++ factorial.cpp Ejemplo 1 #i n c l u d e <i o s t r e a m > Entrada: 6 i n t factorial ( i n t n ){ i f ( n<=0) r e t u r n −1; e l s e i f ( n>15) r e t u r n −1; i f ( n==1) return n ; r e t u r n n∗factorial ( n −1); } Salida: 720 Ejemplo 2 Entrada: -1 i n t main ( ) { int n ,r; std : : cin>>n ; Salida: Un error r=factorial ( n ) ; i f ( r<0) std : : cout<<”Un e r r o r ”<<std : : endl ; else std : : cout<<” e l r e s u l t a d o e s ”<<r<<std : : endl ; return 0; } Cynthia Rodrı́guez (UAM-A) EDOO Ejemplo 3 Entrada: 17 Salida: Un error 2011-O 7 / 21 Manejo de excepciones Ejemplo: C++ factorial.cpp Ejemplo 1 Entrada: 6 #i n c l u d e <i o s t r e a m > Salida: 720 i n t factorial ( i n t n ){ i f ( n<=0) throw ( ” ’ n ’ debe s e r p o s i t i v o ” ) ; e l s e i f ( n>15) throw ( ” ’ n ’ es demasiado grande ” ) ; i f ( n==1) return n ; r e t u r n n∗factorial ( n −1); } Ejemplo 2 Entrada: -1 i n t main ( ) { int n ,r; std : : cin>>n ; try{ r=factorial ( n ) ; } c a t c h ( c h a r ∗s ){ std : : cout<<s<<std : : endl ; return 0; } std : : cout<<” e l r e s u l t a d o e s ”<<r<<std : : endl ; return 0; } Cynthia Rodrı́guez (UAM-A) EDOO Salida: ’n’ debe ser positivo Ejemplo 3 Entrada: 17 Salida: ’n’ es demasiado grande 2011-O 8 / 21 Manejo de excepciones Ejemplo: C++ factorial.cpp Ejemplo 1 #i n c l u d e <i o s t r e a m > Entrada: 6 i n t factorial ( i n t n ){ i f ( n<=0) throw ( ” ’ n ’ debe s e r p o s i t i v o ” ) ; e l s e i f ( n>15) throw ( ” ’ n ’ es demasiado grande ” ) ; i f ( n==1) return n ; r e t u r n n∗factorial ( n −1); } Salida: 720 Ejemplo 2 Entrada: -1 i n t main ( ) { int n ,r; std : : cin>>n ; try{ r=factorial ( n ) ; }catch ( . . . ) { std : : cout<<”Un e r r o r ”<<std : : endl ; return 0; } std : : cout<<” e l r e s u l t a d o e s ”<<r<<std : : endl ; return 0; } Cynthia Rodrı́guez (UAM-A) EDOO Salida: Un error Ejemplo 3 Entrada: 17 Salida: Un error 2011-O 9 / 21 Manejo de excepciones Ejemplo: Java factorial.java i m p o r t java . io . IOException ; i m p o r t java . security . I n v a l i d A l g o r i t h m P a r a m e t e r E x c e p t i o n ; p u b l i c c l a s s Factorial{ p r i v a t e s t a t i c i n t fact ( i n t n ) t h r o w s I n v a l i d A l g o r i t h m P a r a m e t e r E x c e p t i o n { i f ( n<=0) t h r o w new I n v a l i d A l g o r i t h m P a r a m e t e r E x c e p t i o n ( ”n d e b e s e r p o s i t i v o ” ) ; i f ( n>15) t h r o w new I n v a l i d A l g o r i t h m P a r a m e t e r E x c e p t i o n ( ”n e s d e m a s i a d o g r a n d e ” ) ; i f ( n==1) r e t u r n n ; r e t u r n n∗fact ( n −1); } p u b l i c s t a t i c v o i d main ( String args [ ] ) { i n t n =0 , r ; b o o l e a n test=t r u e ; w h i l e ( test ){ try{ i n t c = System . in . read ( ) ; i f ( c>=’ 0 ’ && c<=’ n ’ ) n=10∗n + ( c−’ 0 ’ ) ; e l s e t h r o w new IOException ( ) ; } c a t c h ( IOException e ){ test= f a l s e ; } } t r y { r=fact ( n ) ; } c a t c h ( Exception e ){ System . out . println ( e ) ; r e t u r n ; } System . out . println ( ” E l r e s u l t a d o e s ”+r ) ; r e t u r n ; } } Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 10 / 21 Manejo de excepciones Ejemplo: Java Ejemplo 1 Entrada: 6 Salida: El resultado es 720 Ejemplo 2 Entrada: -1 Salida: java.security.InvalidAlgorithmParameterException: n debe ser positivo Ejemplo 3 Entrada: 17 Salida: java.security.InvalidAlgorithmParameterException: n es demasiado grande Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 10 / 21 Contenido: 1 Manejo de excepciones 2 Entrada y salida por archivos Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 11 / 21 Entrada y salida por archivos Introducción Archivo: Conjunto de bytes con atributos asociados almacenado en un dispositivo externo Operaciones básicas: Apertura Lectura Escritura Cierre Algunos tipos de archivos: Texto: contiene caracteres Binarios: contiene secuencias de bytes Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 12 / 21 Entrada y salida por archivos C++: manejo de archivos Se utilizan las clases ifstream/ofstream de la biblioteca fstream Se debe asociar el objeto ifstream/ofstream a un archivo con el método open. Se puede especificar un modo: ios::in permite operaciones de entrada ios::out permite operaciones de salida ios::ate asigna el final del archivo como posición inicial ios::app todas las operaciones se realizan al final del archivo, sólo para flujos de tipo out ios::trunc si el archivo ya existe, remplaza su contenido ios::noreplace error si el archivo ya existe ios::binary abre como archivo binario los modos se pueden combinar con el operador OR (|) Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 13 / 21 Entrada y salida por archivos C++: apertura de archivos Se debe asociar el objeto ifstream/ofstream a un archivo con el método open. Se puede especificar un modo Ejemplo #i n c l u d e <f s t r e a m> ofstream archivo ; archivo . open ( ” nombre . a r c h i v o ” , ios : : out | ios : : app | ios : : binary ) ; Ejemplo #i n c l u d e <f s t r e a m> ofstream archivo ( ” nombre . a r c h i v o ” , ios : : out | ios : : app | ios : : binary ) ; Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 14 / 21 Entrada y salida por archivos C++: cierre de archivos Se utilizan las clases ifstream/ofstream de la biblioteca fstream Se debe cerrar el flujo a un archivo con el método close. Este método vacı́a los buffers asociados al flujo de datos y cierra el archivo. Ejemplo #i n c l u d e <f s t r e a m> ofstream archivo ( ” nombre . a r c h i v o ” , ios : : out | ios : : app | ios : : binary ) ; archivo . close ( ) ; El objeto fstream puede ser reutilizado para abrir otros archivos. Si no se cierra el flujo, el destructor lo hará automáticamente. Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 15 / 21 Entrada y salida por archivos C++: archivos de texto La entrada y salida de datos usando archivos de texto se hace de manera similar a la entrada y salida estándar archivos.cpp #i n c l u d e <f s t r e a m> #i n c l u d e <i o s t r e a m > u s i n g namespace std ; Entrada i n t main ( ) { ifstream entrada ( ” e n t r a d a . t x t ” ) ; ofstream salida ( ” s a l i d a . t x t ” ) ; char c ; i f ( entrada . is_open ( ) && salida . is_open ( ) ) { w h i l e ( entrada . good ( ) && salida . good ( ) ) { entrada >> c ; salida << c ; } }else{ cout <<” E r r o r a l a b r i r l o s a r c h i v o s \n” ; return 0; } entrada . close ( ) ; salida . close ( ) ; return 0; } ABCDEFG HIJK LMNO PQR STUVW XYZ Cynthia Rodrı́guez (UAM-A) EDOO Salida ABCDEFGHIJKLMNOPQRSTUVWXYZZ 2011-O 16 / 21 Entrada y salida por archivos C++: archivos binarios La entrada y salida de datos se hace con las funciones read/write read/write read(memoria,tamaño); write(memoria,tamaño); memoria: es un apuntador a caracter (char*) tamaño: es el tamaño del bloque de memoria Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 17 / 21 Entrada y salida por archivos C++: archivos de texto archivos.cpp Entrada #i n c l u d e <f s t r e a m> #i n c l u d e <i o s t r e a m > u s i n g namespace std ; i n t main ( ) { ifstream entrada ( ” e n t r a d a . t x t ” , ios : : binary ) ; ofstream salida ( ” s a l i d a B . t x t ” , ios : : binary ) ; char c ; i f ( entrada . is_open ( ) && salida . is_open ( ) ) { w h i l e ( entrada . good ( ) && salida . good ( ) ) { entrada . read (&c , s i z e o f ( c h a r ) ) ; salida . write (&c , s i z e o f ( c h a r ) ) ; } }else{ cout <<” E r r o r a l a b r i r l o s a r c h i v o s \n” ; return 0; } entrada . close ( ) ; salida . close ( ) ; return 0; } Cynthia Rodrı́guez (UAM-A) EDOO ABCDEFG HIJK LMNO PQR STUVW XYZ Salida ABCDEFG HIJK LMNO PQR STUVW XYZ 2011-O 18 / 21 Entrada y salida por archivos Java: manejo de archivos Se utilizan las clases FileInputStream/FileOutputStream del paquete java.io En Java, todos los archivos se tratan como archivos binarios La lectura y escritura de archivos se hacen byte a byte. Se puede utilizar un objeto BufferedReader/BufferedWriter para leer o escribir más bytes a la vez BufferedReader/BufferedWriter br.read(cadena,inicio,tamaño); bw.write(cadena,inicio,tamaño); cadena: es un arreglo de caracteres inicio: es el offset tamaño: es el tamaño de la cadena Cynthia Rodrı́guez (UAM-A) EDOO 2011-O 19 / 21 Entrada y salida por archivos Java: Ejemplo archivos.java i m p o r t java . io . ∗ ; p u b l i c c l a s s Archivos{ p u b l i c s t a t i c v o i d main ( String args [ ] ) { F il eI np u tStream entrada ; F i l e O u t p utStream salida ; int c; try{ entrada = new FileInputStream ( ” e n t r a d a salida = new FileOutputStream ( ” s a l i d a J } c a t c h ( Exception e ){ System . out . println ( ” E r r o r a l a b r i r l o s return ; } do{ try{ c = entrada . read ( ) ; salida . write ( c ) ; } c a t c h ( Exception e ){ System . out . println ( ” E r r o r a l c o p i a r return ; } } w h i l e ( c != −1); return ; } } Cynthia Rodrı́guez (UAM-A) Entrada . txt ” ); . txt ” ); ABCDEFG HIJK LMNO PQR STUVW XYZ archivos ” ); Salida el archivo ” ); EDOO ABCDEFG HIJK LMNO PQR STUVW XYZ 2011-O 20 / 21 Entrada y salida por archivos Java: Ejemplo archivosBuffered.java i m p o r t java . io . ∗ ; p u b l i c c l a s s ArchivosBuffered{ p u b l i c s t a t i c v o i d main ( String args [ ] ) t h r o w s Exception{ Buff eredReader entrada ; Buff eredWriter salida ; int l; c h a r [ ] c = new c h a r [ 1 1 ] ; try{ entrada = new BufferedReader ( new FileReader ( ” e n t r a d a . t x t ” ) ) ; salida = new BufferedWriter ( new FileWriter ( ” s a l i d a J B . t x t ” ) ) ; } c a t c h ( Exception e ){ System . out . println ( ” E r r o r a l a b r i r l o s f l u j o s ” ) ; r e t u r n ; } do{ try{ l = entrada . read ( c , 0 , 1 0 ) ; i f ( l>0) salida . write ( c , 0 , l ) ; } c a t c h ( Exception e ){ System . out . println ( ” E r r o r a l c o p i a r e l a r c h i v o : ”+e ) ; return ; } } w h i l e ( l != −1); entrada . close ( ) ; salida . close ( ) ; r e t u r n ; } } Cynthia Rodrı́guez (UAM-A) EDOO Entrada ABCDEFG HIJK LMNO PQR STUVW XYZ Salida ABCDEFG HIJK LMNO PQR STUVW XYZ 2011-O 21 / 21