2012-01-20 6 views
18

친구에게 Java에 대해 많이 알지 못하는 Java 코드를 작성하도록 도와주었습니다. 그래서 나는 그에게 약간의 도우미 기능을 썼다. 그 중 하나는 OutputStream에 문자열을 쓰는 함수입니다. 살펴보기 :System.out이 폐쇄 되었습니까? 다시 열 수 있습니까?

public void write(String txt, OutputStream out) { 
    PrintWriter printer = new PrintWriter(out); 
    printer.print(txt); 
    printer.close(); 
} 

이제 어디서든 원하는대로 쓸 수 있습니다. 내가 나중에 System.out.println() 더 이상 쉘에 아무것도 기록하지 않는 것을 발견 하

(new StreamHelper()).write("Hello Test", System.out); 

: 예를 들어, 당신은 그렇게 할 수 있습니다. 그래서 나는 아마도 printer.close()도 자동으로 System.out을 닫았을 것이라고 생각합니다.이 함수가 다시 끝난 후에 다시 사용할 수있는 방법을 생각해 봅니다.

내 가정이 맞습니까? (여기에 묻지 않고 어떻게 알 수 있습니까?)

write() 함수 호출 후 System.out을 어떻게 계속 사용할 수 있습니까?

이러한 도우미 함수를 작성하는 더 좋은 방법이 있습니까?

+3

I를 위해 유용하게 할 수 있음 그러나이 같은 폐쇄하기로 스트림을 보호하기 위해 외관을 쓸 수 믿어, 당신은'close()'대신'flush'를 사용할 수 있습니다. –

+1

추한'(새로운 StreamHelper()). write (...)'호출을 피하기 위해'write' 메소드를'static'으로 만들 수 있습니다. – adarshr

+2

@Stas Kurilin : 나는 그것을 시도하고 작동합니다. – erikbwork

답변

19

가까운 OutputStream 년대의 일반 규약 :

공공 무효 close()를 는 IOException가이 출력 스트림을 닫아이 스트림에 관련하는 모든 system resource를 해방시킵니다. 닫기의 일반 계약 은 출력 스트림을 닫는 것입니다. 닫힌 스트림은 출력 작업을 수행 할 수 없으며 은 다시 열 수 없습니다..

PrintStream

public void close() 스트림을 닫습니다. 이 작업은 스트림을 플러시 한 다음 을 사용하여 기본 출력 스트림을 닫음으로써 수행됩니다. 나는 당신을 줄 수

유일한 조언은 당신이 당신의 코드가 다른 곳으로 만들었습니다 자원의 폐쇄를 위임하지 않는, 즉, asymmetrical code를 작성하지해야한다는 것입니다.

경우에 따라 래퍼 스트림을 닫는 것이 현명하게 보일 수도 있지만 사실 다른 곳에서 열린 스트림을 닫으므로해서는 안됩니다.한마디로

:

public void write(String txt, OutputStream out) { 
    PrintWriter printer = new PrintWriter(out); 
    printer.print(txt); 
    printer.flush(); 
    //it is very unpolite to close someone else's streams! 
    //printer.close(); 
} 

아, 그리고 그건 그렇고, 당신은 오히려 write보다 print에 함수 이름을 변경할 수 있습니다.

+0

나는 그것이 문제에 대한 해답을 포함하고 있다고 생각한다. 모두의 도움에 감사드립니다! – erikbwork

3

System.out은 PrintStream이므로 위 코드는 문자 그대로 System.out.print을 호출하는 것 이상의 이점이 없습니다. 더 이상 쓰지 않는 이유는 close이 사실은 System.out입니다.

로깅을위한 것이라면, 친구를 위해 log4j를 배우거나 배우게하십시오. Log4j는 파일 스트림, 표준 출력 등에 동시에 쓰기가 필요한 상황을 처리합니다.

+2

아주. 그것은 당신이 다른 스트림뿐만 아니라 System.out을 사용할 수 있다는 점에서 추상화의 이점을 가지고 있습니다. –

+2

로깅과 같은 추상화가 실제로 필요한 유스 케이스가 없다면, 그것은 단지 무의미합니다. –

3

out 입력이 전달되었는지 확인하고 System.out을 선택하여 닫지 않도록 선택할 수 있습니다.

flush() 전화가 필요합니다. 이 write 메서드를 System.out 인수와 함께 호출하면 참조가 동일하므로 == 검사를 수행 중입니다.

public void write(String txt, OutputStream out) { 
    PrintWriter printer = new PrintWriter(out); 
    printer.print(txt); 
    printer.flush(); 

    if(out != System.out) { 
     printer.close(); 
    } 
} 

하지만 솔직히, 나는 폐쇄에 대해 다른 방법을 유지하거나 혼동을 피하기 위해이 방법 writeAndClose을 부를 것이다.

추상화를 유지하려면 (@Urs이 암시 함) 다음을 수행하십시오. 그러나 나는 오히려 을 통해 엔지니어링

public void write(String txt, OutputStream out) { 
    PrintWriter printer = new PrintWriter(out); 
    printer.print(txt); 
    printer.flush(); 
} 

public void close(OutputStream out) { 
    out.close(); 
} 
+0

원래 솔루션으로 생성 된 추상화가 중단됩니다. –

2

하는의보기의 호출자의 관점에서이 보자이 지점이 표시되지 않습니다.

발신자의 전화 번호는 OutputStream이며 어떤 전화 번호는 write()입니다. 호출이 완료되면 호출자는 스트림이 닫혔 음을 발견합니다.

내 생각에 write() 메서드는 printer.close()을 호출하면 안됩니다. 후자는 호출자가 제공하는 스트림을 닫고 호출자가 기대하는 것이 아닐 수도 있습니다.

스트림을 플러시해야하는 경우 flush()을 사용할 수 있습니다.

2

Stur Kurilin이 제안하는 것을 수행하십시오.

일반적으로 스트림을 열거 나 생성 한 당사자가 스트림을 닫아야합니다.

메서드에서 스트림을 그냥 플러시하십시오. 더 이상 필요하지 않을 때 열어 둔 곳에 닫으십시오.

+0

+1 내 이름 홍보) –

9

다른 사람들과 마찬가지로 스트림은 열린 곳에서 닫혀 있어야합니다.

import java.io.FilterOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 

public class UnclosableOutputStream extends FilterOutputStream { 

    public UnclosableOutputStream(OutputStream out) { 
     super(out); 
    } 

    @Override 
    public void close() throws IOException { 
     out.flush(); 
    } 
} 

과 같이 사용 :

new StreamHelper().write("Hello Test", new UnclosableOutputStream(System.out)); 

이 테스트 시나리오 등

관련 문제