System.out关闭了吗?我可以重新打开吗?

eri*_*ork 20 java io

我正在帮朋友写一些Java代码,他们对Java知之甚少.所以我给他写了一些辅助函数来轻松完成他眼中有点古怪的事情.其中一个是一个函数,它将一个String写入一个OutputStream.看一看:

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

现在,您可以通过不同的方式轻松地使用它来编写您想要的任何位置.例如,你可以这样做:

(new StreamHelper()).write("Hello Test", System.out);
Run Code Online (Sandbox Code Playgroud)

这样做我发现之后System.out.println()不再向shell写任何东西了.所以我认为也许会printer.close()自动关闭System.out,我想知道如何重新激活它,我可以在此功能再次完成后使用它.

我的假设是否正确?(如果不问这里我怎么能找到?)

如何System.out在调用该write()函数后继续使用?

是否有更好的方法来编写这样的辅助函数?

for*_*ran 20

一般合同OutputStream的结束:

public void close()throws IOException关闭此输出流并释放与此流关联的所有系统资源.close的一般合同是它关闭输出流.封闭流无法执行输出操作,无法重新打开.

PrintStream

public void close()关闭流.这是通过刷新流然后关闭底层输出流来完成的.

我能给你的唯一建议是你不应该编写不对称代码,也就是说,不要将代码创建的资源关闭委托给其他地方.

即使在你的情况下,关闭包装器流似乎也是明智的,事实是你不应该因为你正在关闭在其他地方打开的流.

简而言之:

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();
}
Run Code Online (Sandbox Code Playgroud)

哦,顺便说一句,你可能想要更改函数名称print,而不是write.


Tim*_*the 11

像其他人所说的那样,流应该在打开的地方关闭.但是,您可以编写一个外观来保护流不被关闭,如下所示:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

new StreamHelper().write("Hello Test", new UnclosableOutputStream(System.out));
Run Code Online (Sandbox Code Playgroud)

对于测试场景等可能会派上用场.