How can I force a CipherOutputStream to finish encrypting but leave the underlying stream open?
I have a CipherOutputStream backed by another OutputStream. After I have finished writing all the data I need encrypted to the CipherOutputStream, I need to append some unencrypted data.
The documentation for CipherOutputStream says that calling flush()
will not force the final block out of the encryptor; for that I need to call close()
. But close()
also closes the underlying OutputStream, which I still need to write more to.
How can I force the last block out of the encryptor without clo开发者_如何学Pythonsing the stream? Do I need to write my own NonClosingCipherOutputStream?
If you don't have a reference to the Cipher
, you could pass a FilterOutputStream
to the method that creates the CipherOutputStream
. In the FilterOutputStream
, override the close
method so that it doesn't actually close the stream.
maybe you can wrap your outputstream before putting into an cipheroutputstream
/**
* Represents an {@code OutputStream} that does not close the underlying output stream on a call to {@link #close()}.
* This may be useful for encapsulating an {@code OutputStream} into other output streams that does not have to be
* closed, while closing the outer streams or reader.
*/
public class NotClosingOutputStream extends OutputStream {
/** The underlying output stream. */
private final OutputStream out;
/**
* Creates a new output stream that does not close the given output stream on a call to {@link #close()}.
*
* @param out
* the output stream
*/
public NotClosingOutputStream(final OutputStream out) {
this.out = out;
}
/*
* DELEGATION TO OUTPUT STREAM
*/
@Override
public void close() throws IOException {
// do nothing here, since we don't want to close the underlying input stream
}
@Override
public void write(final int b) throws IOException {
out.write(b);
}
@Override
public void write(final byte[] b) throws IOException {
out.write(b);
}
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
out.write(b, off, len);
}
@Override
public void flush() throws IOException {
out.flush();
}
}
hope that helps
If you have a reference to the Cipher
object that the CipherOutputStream
wraps, you should be able to do what CipherOutputStream.close()
does:
Call Cipher.doFinal, then flush()
the CiperOutputStream, and continue.
精彩评论