开发者

How can I force a CipherOutputStream to finish encrypting but leave the underlying stream open?

开发者 https://www.devze.com 2023-02-19 21:09 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消