2011-02-05 34 views
12

Khi đọc từ một tệp văn bản, thông thường, hãy tạo ra một FileReader và sau đó tổ rằng trong một số BufferedReader. Tôi nên đóng hai người đọc nào khi đọc xong? Nó có quan trọng không?Đóng trình đọc lồng nhau

FileReader fr = null; 
BufferedReader br = null; 
try 
{ 
    fr = new FileReader(fileName); 
    br = new BufferedReader(fr); 
    // ... 
} 
finally 
{ 
    // should I close fr or br here? 
} 

Tôi hơi hoang tưởng khi nói đến ngoại lệ an toàn. Điều gì xảy ra khi nhà xây dựng BufferedReader ném một ngoại lệ? Nó có đóng trình đọc lồng nhau không? Hoặc là nó đảm bảo không để ném?

Trả lời

9

Nói chung, close() trên trình bao bọc luồng ngoài cùng sẽ gọi close() trên luồng được bao bọc. Tuy nhiên, nếu bạn nghĩ rằng có khả năng một nhà xây dựng sẽ ném một ngoại lệ, hãy sử dụng tự do giao diện Closeable.

FileReader fr = new FileReader(fileName); 
Closeable res = fr; 
try { 
    BufferedReader br = new BufferedReader(fr); 
    res = br; 
} finally { 
    res.close(); 
} 

Vì vậy, ngay cả khi JVM hết dung lượng bộ nhớ đệm và đã phát hiện lỗi, bạn sẽ không bị rò rỉ xử lý tệp.

Đối với Java 7 trở lên sử dụng thử-với-nguồn:

try (FileReader fr = new FileReader(fileName); 
    BufferedReader br = new BufferedReader(fr)) { 
    // do work 
} 
+1

+1. Thanh lịch hơn nhiều so với giải pháp của tôi. –

+0

Giải pháp tốt nếu bạn đang làm việc với nhiều trình bao bọc có thể ném ngoại lệ (và tương tự). Tất nhiên, bạn có thể kiểm tra tài liệu và mã của 'BufferedReader' để xem liệu có thực sự có bất kỳ cơ hội nào của một ngoại lệ trong ctor hay không. – fwielstra

0

Chỉ đóng BufferedReader là đủ, khiến nó kết thúc tốt đẹp FileReader. Nếu bạn nhìn vào số source code của BufferedReader, bạn sẽ thấy phương thức close, đóng luồng được bao bọc.

+0

'buf = new char [8192];' Ew, số ma thuật! – fredoverflow

0

Đóng BufferedReader trong khối cuối cùng.

0

Nếu bạn gọi phương thức đóng của BufferedReader, các BufferedReader sẽ gọi phương thức đóng của FileReader. Do đó cả hai phương pháp đóng được gọi. Chính xác hơn, BufferedReader sẽ không làm gì cả NHƯNG gọi phương thức đóng của FileReader. Do đó nó không quan trọng chút nào. Mặc dù tôi nghĩ rằng đó là thực hành tốt quá gọi phương thức đóng của BufferedReader.

0

Không có gì đảm bảo không được ném. Bởi vì bộ đệm được cấp phát, nó có thể ném OutOfMemoryError. Tôi thường tách mã của tôi thành 2 phần: nhận tài nguyên và sau đó sử dụng tài nguyên. Mỗi phần thường có dọn dẹp độc đáo cần

Đây là đoạn mã để minh họa:

// Acquire resources section. 

final FileReader fr = new FileReader(fileName); 

BufferedReader br = null; 

try 
{ 
    br = new BufferedReader(fr); 
} 
finally 
{ 
    if (br == null) 
    { 
     // Note that you are closing the fr here 
     fr.close(); 
    } 
} 

// Use resources section 
try 
{ 
    // ... use br 
} 
finally 
{ 
    // Now that br is safely constructed, just all its close 
    br.close(); 
} 

Và tôi đồng ý với bạn, không có gì đáng hơn âm thầm mất một handler tập tin trong ứng dụng máy chủ chạy dài là.