2009-07-08 26 views
29

Vì không có khoản cuối cùng để khối try-catch trong MATLAB, tôi thấy mình viết rất nhiều mã như sau:Làm thế nào để bạn xử lý tài nguyên trong MATLAB một cách ngoại lệ an toàn? (Như "thử ... cuối cùng")

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); 

tôi thấy có fclose chức năng ở hai nơi xấu xí và dễ bị lỗi.

Có cách nào tốt hơn để thực hiện việc này không?

+3

Đây chỉ là một điểm nhỏ, nhưng tôi khuyên bạn không nên sử dụng tên biến "dòng" trong mã của bạn. Nó có thể kết thúc gây ra một số nhầm lẫn vì đã có sẵn một chức năng gọi là LINE. – gnovice

+0

Ngoài ra, hãy kiểm tra http://stackoverflow.com/questions/8847866/how-can-i-close-files-that-are-left-open-after-an-error –

Trả lời

35

Tôi khuyên bạn nên xem các đối tượng ONCLEANUP. Chúng cho phép bạn tự động chạy mã khi thoát khỏi một hàm (cụ thể hơn, khi đối tượng ONCLEANUP được xóa khỏi bộ nhớ). Loren from The MathWorks thảo luận về điều này trong một bài đăng trên blog của cô here. Nếu bạn đặt mã trên của bạn trong một chức năng, nó có thể trông giống như thế này:

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 

Thậm chí nếu cuộc gọi đến GETL ném một ngoại lệ, đối tượng ONCLEANUP vẫn sẽ được xóa khỏi bộ nhớ khi trở về từ hàm load_line, do đó đảm bảo tệp bị đóng.

+2

Cảm ơn. Đó chính xác là những gì tôi đang tìm kiếm. Tôi đã thực hiện một số đọc thêm xung quanh các lớp học onCleanup và phong cách mới trong Matlab nói chung, và có vẻ như với tôi rằng bây giờ với các lớp học xử lý, bạn có thể thực hành RAII thích hợp trong Matlab đó là rất tốt. – snth

+0

onCleanup lần đầu tiên được giới thiệu trong MATLAB 7.6 (R2008a). Bạn đề nghị gì cho những người phải duy trì tính tương thích với các phiên bản cũ hơn (đặc biệt là R2006b)? – rob

+1

@rob: Tôi khuyên bạn nên yêu cầu người dùng không cho phép phần mềm của họ bị lỗi 7 năm. ;) Câu trả lời nghiêm túc: vì R2006b cho phép lập trình hướng đối tượng, làm cho một lớp để xử lý tệp I/O là cách tôi muốn đi, như được đề xuất trong câu trả lời của [Nzbuu] (http://stackoverflow.com/a/ 9024064/52738) và câu trả lời của [câu hỏi liên quan này] (http://stackoverflow.com/q/8847866/52738). – gnovice

7

Tùy chọn của tôi là tạo một lớp FileHandle với phương thức delete đóng tệp khi đối tượng nằm ngoài phạm vi. Cũng cung cấp cho bạn cơ hội để thực hiện các công cụ xử lý tệp tự nhiên khác.

+0

Giải thích thêm tại đây - http://stackoverflow.com/questions/8847866/how-can-i-close-files-that-are-left-open-after-an-error –

+0

Hey! Đó là ý tưởng của tôi;) – Nzbuu

Các vấn đề liên quan