Как заставить CipherOutputStream завершить шифрование, но оставить основной поток открытым? - PullRequest
8 голосов
/ 27 марта 2011

У меня есть CipherOutputStream, подкрепленный другим OutputStream.После того, как я закончу запись всех данных, которые мне нужно зашифровать, в CipherOutputStream, мне нужно добавить некоторые незашифрованные данные.

В документации для CipherOutputStream сказано, что вызов flush() не заставит окончательнозаблокировать из шифратора;для этого мне нужно позвонить close().Но close() также закрывает базовый OutputStream, в который мне еще нужно записать больше.

Как я могу принудительно заставить последний блок выйти из шифратора, не закрывая поток?Нужно ли мне писать свой собственный NonClosingCipherOutputStream?

Ответы [ 3 ]

8 голосов
/ 27 марта 2011

Если у вас нет ссылки на Cipher, вы можете передать FilterOutputStream методу, который создает CipherOutputStream. В FilterOutputStream переопределите метод close, чтобы он не закрывал поток.

1 голос
/ 16 августа 2013

возможно, вы можете обернуть свой выходной поток перед тем, как поместить его в зашифрованный выходной поток

/**
 * 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();
    }
}

надеюсь, что это поможет

0 голосов
/ 27 марта 2011

Если у вас есть ссылка на объект Cipher, который обертывает CipherOutputStream, вы сможете делать то, что CipherOutputStream.close() делает:

Вызовите Cipher.doFinal , затем flush() CiperOutputStream и продолжайте.

...