2013-06-04 21 views
7

Khi cần đóng luồng đầu ra, chúng tôi có hai lựa chọn.Tôi có nên sử dụng phương thức close hoặc closeQuietly để đóng luồng đầu ra không?

  1. closeQuietly có nghĩa là đóng luồng không có ngoại lệ.

    try { 
        close(out) 
    } catch(IOException e) { 
    } 
    
  2. gần

    try { 
        close(out) 
    } catch(IOException e) { 
        throw anException; 
    } 
    

như được biết, dòng sản lượng sẽ viết một/một vài ký tự vào cuối tập tin khi đóng cửa, nếu các văn bản sai, tập tin cũng có thể không được mở chính xác như ZipoutputStream.

nếu tôi sử dụng thẻ đầu tiên, tôi sẽ gặp phải một số nguy cơ không đóng được. nếu tôi sử dụng thẻ thứ hai, nó sẽ cho phép mã của tôi không thân thiện.

Ai đó có thể cho tôi một số lời khuyên không?

Rất tiếc vì đã mô tả sự cố không rõ ràng.

Tôi có nghĩa là cách thực hiện thao tác IO một cách an toàn. nếu bản phát hành của tài nguyên bị lỗi, nó sẽ cho phép người gọi biết.

Cảm ơn tất cả câu trả lời của bạn. Và đặc biệt cảm ơn @Don Roby đã cho tôi một liên kết, trong đó có câu trả lời tốt nhất trả lời bằng cách @Fabian Barney

+0

bản sao có thể có của [Có an toàn để sử dụng Apache commons-io IOUtils.closeQuietly?] (Http://stackoverflow.com/questions/14436453/is-it-safe-to-use-apache-commons-io- ioutils-closequietly) –

+0

'catch (IOException e) {ném một ngoại lệ; } 'là vô nghĩa - bạn cần khai báo' ném IOException' để làm điều đó, vì vậy bạn cũng có thể bỏ qua try/catch – artbristol

Trả lời

11

Kể từ Java 7 IOUtils.closeQuietly trở nên lỗi thời và các giải pháp hợp lý duy nhất là try-with-resources mà đóng nguồn tự động

try (InputStream is = new FileInputStream(file)) { 
    ... 
} 

Note rằng nó cũng giải quyết vấn đề với việc mở một cách chính xác/đóng nhiều hơn một nguồn

try (InputStream is = new FileInputStream(infile); OutputStream out = new FileOutputStream(outfile)) { 
    ...   
} 

Và nó cũng không ngăn chặn IOException rằng close() có thể ném, w hich là chính xác những gì closeQuietly nào.

3

Một số triển khai của close() có thể bao gồm logic khác như viết byte cuối cùng hoặc flush() 'ing dữ liệu. Ví dụ là FilterOutputStream.

Bây giờ, hãy hình ảnh một tình huống khi luồng dựa trên kênh mạng hoặc ổ USB gắn ngoài. Cả hai có thể biến mất bất cứ lúc nào. Nó có thể xảy ra khi thực hiện close().

Vì vậy, quan điểm của tôi: bắt IOException và ném ngoại lệ ứng dụng cụ thể của bạn với bao gồm nguyên nhân ngoại lệ, như:

} catch (IOException e) 
{ 
    throw new IOManagementException(e); 
} 

Nếu bạn đang dính trên không ném ngoại lệ, sau đó đăng nhập nếu với tình trạng LỖI ít nhất .

nếu không thực hiện, có thể dẫn đến rất khó phân tích báo cáo lỗi hoặc hành vi lạ.

+0

đó là một câu trả lời hay, nhưng nó sẽ cho phép mã của tôi không thân thiện. Tôi đã biết một giải pháp khác, đó là thử {..... out.close();} catch (IOException e) {ném một ngoại lệ;} cuối cùng {IOUtils.closeQuietly (out)} –

0

Như một quy tắc của ngón tay cái, tôi không bao giờ nuốt ngoại lệ, vì vậy tùy thuộc vào logic theo yêu cầu của mã Tôi viết thư này, tôi có thể

  1. Đăng trừ:

    try { 
        close(out); 
    } catch(IOException e) { 
        // log the exception 
        log.info("An error has occurred during stream closing: {}", e); 
    } 
    
  2. Gói nó ném thêm nữa

    try { 
        close(out); 
    } catch(IOException e) { 
        throw new MyException(e); 
    } 
    

Kể từ JDK 7 là xung quanh, tôi thích (như đã đề cập bởi Evgeniy) để sử dụng thử-với-nguồn:

try (OutputStream out = // create output stream) { 
    // do the writing 
} // at this point the stream is closed 

này sẽ kết thúc một cách thích hợp và an toàn luồng mà bạn đang đối phó với.

0

Làm sạch mã là điều tốt nhưng khi nào xâm phạm nó có thể cung cấp cho bạn kết quả tốt hơn như bảo trì, Gỡ lỗi trong trường hợp này chúng ta nên làm điều đó. Nó có thể được thực hiện một cách tốt hơn như ngoại lệ tùy chỉnh hoặc sử dụng tính năng Java7 như đề xuất ở trên nhưng chi phí viết thêm vài dòng là giá trị nó theo kinh nghiệm của tôi.