2009-07-08 19 views
29

Puesto que no hay fin a la cláusula de bloque try-catch en MATLAB, me encuentro escribiendo un montón de código como el siguiente:¿Cómo se manejan los recursos en MATLAB de una manera segura y excepcional? (Como "try ... finally")

fid = fopen(filename); 
if fid==-1 
    error('Couldn''t open file'); 
end 
try 
    line = getl(fid); 
catch ME 
    fclose(fid); 
    rethrow ME; 
end 
fclose(fid); 

Me parece que tiene la fclose función en dos lugares feo y propenso a errores.

¿Hay una mejor manera de hacerlo?

+3

Este es solo un punto menor, pero sugeriría no usar el nombre de variable "línea" en su código. Podría terminar causando confusión ya que ya hay una función incorporada llamada LINE. – gnovice

+0

También verifique http://stackoverflow.com/questions/8847866/how-can-i-close-files-that-are-left-open-after-an-error –

Respuesta

35

Yo sugeriría retirar ONCLEANUP objects. Le permiten ejecutar automáticamente el código al salir de una función (más específicamente, cuando el objeto ONCLEANUP se borra de la memoria). Loren from The MathWorks habla de esto en una de sus entradas de blog here. Si coloca el código anterior en una función, que podría ser algo como esto:

function data = load_line(filename) 
    data = []; 
    fid = fopen(filename); 
    if fid == -1 
     error('Couldn''t open file'); 
    end 
    c = onCleanup(@()fclose(fid)); 
    data = getl(fid); 
end 

Incluso si la llamada a GETL lanza una excepción, el objeto ONCLEANUP todavía será borrado de la memoria en la declaración de la load_line función , lo que garantiza que el archivo se cierre.

+2

Gracias. Eso es exactamente lo que estaba buscando. He leído un poco más sobre el onCleanup y las nuevas clases de estilo en Matlab en general, y me parece que ahora con clases de manejo puedes practicar RAII adecuada en Matlab, que es genial. – snth

+0

onCleanup se introdujo por primera vez en MATLAB 7.6 (R2008a). ¿Qué sugiere para las personas que tienen que mantener la compatibilidad con versiones anteriores (en particular, R2006b)? – rob

+1

@rob: Sugeriría decirle a los usuarios que no dejen que su software tenga 7 años de retraso. ;) La respuesta seria: dado que R2006b permite la programación orientada a objetos, hacer que una clase maneje las E/S de archivos es lo que yo haría, como se sugiere en [respuesta de Nzbuu] (http://stackoverflow.com/a/ 9024064/52738) y las respuestas de [esta pregunta relacionada] (http://stackoverflow.com/q/8847866/52738). – gnovice

7

Mi preferencia es crear una clase FileHandle con un método delete que cierra el archivo cuando el objeto queda fuera del alcance. También le da la oportunidad de hacer otras cosas más naturales para manejar archivos.

+0

Más explicación aquí - http://stackoverflow.com/questions/8847866/how-can-i-close-files-the-are-left-open-after-an-error –

+0

¡Hola! Esa es mi idea;) – Nzbuu

Cuestiones relacionadas