Java 有没有一种方法可以在不关闭底层流的情况下关闭Writer?
我有一个套接字,我在其中写入一些字符数据和一些原始字节数据。对于字符数据,更容易使用Java 有没有一种方法可以在不关闭底层流的情况下关闭Writer?,java,sockets,io,outputstream,Java,Sockets,Io,Outputstream,我有一个套接字,我在其中写入一些字符数据和一些原始字节数据。对于字符数据,更容易使用PrintWriter。对于原始字节数据,直接写入OutputStream更容易。因此,在我的代码中,我有如下片段: Writer writer = new PrintWriter(outputStream); writer.write(someText); ... writer.flush(); // No call to writer.close(), because that would close the
PrintWriter
。对于原始字节数据,直接写入OutputStream
更容易。因此,在我的代码中,我有如下片段:
Writer writer = new PrintWriter(outputStream);
writer.write(someText);
...
writer.flush();
// No call to writer.close(), because that would close the underlying stream.
只要我小心不要在开始以其他方式写入流之后写入此编写器
,就可以了。但我更希望安全地知道,如果我不小心写入流,我会得到一个IOException
(如果我关闭了它,我也会这样做)
有没有一种方法可以在不关闭底层流的情况下显式防止将来对
编写器的写入?简单地说,没有。Java io流类的编写方式总是链接关闭操作。当然,您可以创建自己的writer实现来覆盖此行为。为什么close()
只做两件事:(1)刷新写入程序;(2)调用嵌套写入程序上的close()
。如果不需要(2),请自己调用flush()
,根本不调用close()
。我将创建一个特殊类,允许同时写入字符和二进制数据,类似于:
class CombinedWriter extends Writer {
private boolean isWritingBinary;
private Writer mWriter;
private OutputStream mOutputStream;
public void write(byte[] bytes) {
// flush the writer if necessary
isWritingBinary = true;
mOutputStream.write(bytes);
}
public void write(String string) {
// flush if necessary
isWritingBinary = false;
mWriter.write(string);
}
public void flush() {
// ...
}
public void close() {
// ...
}
}
它可以扩展或不扩展Writer
;在后一种情况下,不需要重写代码中未使用的方法
writer flush的技巧仍然存在,但它只局限于一个类;此外,如果该技巧在将来的某个版本中失效,则可能会重写该类以消除该技巧(可能需要从Android源代码借用一部分代码)。以下是如何对字符和二进制数据使用OutputStream:
byte strBin[] = someText.getBytes("UTF-8");
outputStream.write(strBin);
如果需要编码,请替换“UTF-8”。谢谢您的询问!我也有同样的问题,而且很容易解决。通过阅读你的问题,听起来你可能正试图做我想做的事情,所以我想通过给出对我有效的解决方案来帮助你
在我的例子中,我试图为jpg编写一个HTTP响应,在这种情况下,文本头部分后面将跟随二进制数据。这里的流是JavaSocket
的OutputStream
我使用PrintWriter
将文本写入套接字流,但随后需要写入二进制数据。有一个简单的解决方案,它的工作原理与文本数据之后是二进制数据的情况相同,并且在二进制数据之后没有更多的文本数据
只需在流上打开一个Printwriter
,然后使用writer将文本打印到流中,直到所有文本都被写入。然后将PrintWriter
刷新到流中,但不要关闭它(这将关闭底层流,底层流必须保持打开状态)。最后,将二进制数据直接写入流
最后,您只需关闭PrintWriter
即可关闭底层流
如果使用下面提供的类,您将:
通过为底层套接字提供OutputStream
来构造HttpStreamWriterImpl
根据需要反复调用writeLine()
根据需要调用writeBinary()
完成后调用close()
例如:
public class HttpStreamWriterImpl implements Closeable
{
private @NotNull OutputStream stream;
private @NotNull PrintWriter printWriter;
public HttpStreamWriterImpl(@NotNull OutputStream stream)
{
this.stream = stream;
this.printWriter = new PrintWriter(stream, true, UTF_8);
}
public void writeLine(@NotNull String line)
{
printWriter.print(line);
printWriter.print(HTTP_LINE_ENDING);
}
public void writeBinary(@NotNull byte[] binaryContent) throws IOException
{
printWriter.flush();
stream.write(binaryContent);
stream.flush();
}
@Override
public void close()
{
printWriter.close();
}
}
最好使用java.nio.charset
包中的StandardCharsets.UTF_8
,而不是在Java7上使用字符串文字硬编码名称+