Thanks for asking! I had exactly the same problem, and it was easy to solve. From reading your question it sounds like you might be trying to do exactly what I was trying to do, so I wanted to help out by giving the solution that worked for me.
In my case I was trying to write a HTTP response for a jpg, in which case the text header section will be followed by binary data. The stream here is the OutputStream
of a Java Socket
.
I was using a PrintWriter
to write text to the socket stream, but then I needed to write the binary data. There is an easy solution, which works as-is for the case where binary data follows text data, and there is no more text data after the binary data.
Simply open a Printwriter
on the stream and use the writer to print text into the stream until all the text is written. Then flush the PrintWriter
to the stream, but don't close it (that closes the underlying stream, which must stay open). Lastly, write the binary data directly to the stream.
At the end you may simply close the PrintWriter
to close the underlying stream.
If using the class provded below, you would:
- Construct the
HttpStreamWriterImpl
by providing the OutputStream
for the underlying Socket
.
- Call
writeLine()
repeatedly as needed.
- Call
writeBinary()
if/as needed.
- Call
close()
when finished.
Example:
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();
}
}
StandardCharsets.UTF_8
fromjava.nio.charset
package rather than hard coding the name using string literal on java 7+ – Suziesuzuki