简体   繁体   中英

The Flush method of outputstream does nothing

Trying something that envolves partially encrypting a file. All is well except this little problem. For some reason. the flush method does work until n > 52 where n is count of loops. You can see it in the decryption method. If i change the n fomr < 10 to < 53 it flushes. I tested it by looking at the file. no new contents are added until 53. But there should be.

public class DesEncrypter {
Cipher ecipher;
Cipher dcipher;

DesEncrypter(SecretKey key) {
    // Create an 8-byte initialization vector
    byte[] iv = new byte[]{
        (byte)0x8E, 0x12, 0x39, (byte)0x9C,
        0x07, 0x72, 0x6F, 0x5A
    };
    AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
    try {
        ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

        // CBC requires an initialization vector
        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
    } catch (java.security.InvalidAlgorithmParameterException e) {
    } catch (javax.crypto.NoSuchPaddingException e) {
    } catch (java.security.NoSuchAlgorithmException e) {
    } catch (java.security.InvalidKeyException e) {
    }
}

// Buffer used to transport the bytes from one stream to another
byte[] buf = new byte[1024];

public void encrypt(InputStream in, OutputStream out) {
    try {
        // Bytes written to out will be encrypted
       AppendableOutputStream out_append = new AppendableOutputStream(out);

       OutputStream out_c = new CipherOutputStream(out_append, ecipher);

        // Read in the cleartext bytes and write to out to encrypt
        int numRead = 0;
        int count = 0;
        int max = 1024;
        boolean first = true;

        while ((numRead = in.read(buf, 0, max)) > 0) {                 
            System.out.println("running Total: " + count);
            count += numRead;
            // if this read puts as at less than a meg, encrypt
            if(count <= 1024*1024){
                System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count);
                out_c.write(buf, 0, numRead);
                // last encryption pass, close buffer and fix max
                if(count == 1024*1024){
                    // fix reading 1k in case max was decreased
                    max = 1024;
                    out_c.close();
                }
                // if next read will go over a meg, read less than 1k
                else if(count + max > 1024*1024)
                    max = 1024*1024 - count;
            }
            // past the first meg, don't encrypt
            else{
                System.out.println("processed " + numRead + " of " + max +" bytes : total " + count);
                out.write(buf, 0, numRead);
            }

        }
        out.close();

    } catch (java.io.IOException e) {}

}

// Movies encrypt only 1 MB 128 passes.

public void decrypt(InputStream in, OutputStream out) {
    try {
        // Bytes read from in will be decrypted
        InputStream in_c = new CipherInputStream(in, dcipher);

        // Read in the decrypted bytes and write the cleartext to out
        int numRead = 0;
        int count = 0;
        int max = 1024;

        while ((numRead = in_c.read(buf, 0, max)) > 0) {
            count += numRead;
            System.out.println("decrypted " + numRead + " of " + max +" bytes : total " + count);
            out.write(buf, 0, numRead);
            if(count + max > 1024*1024){
                max = 1024*1024 - count;
            }
            if(count == 1024*1024)
                max = 0;
        }

        //in.skip(count);
        int n = 0;
        while((numRead = in.read(buf)) > 0 && n < 10){
        count += numRead;
        System.out.println("processed " + numRead + " of 1024 bytes : total " + count);
            out.write(buf,0,numRead);
            //System.out.println("buf"+buf.length  +" numered" + numRead+ " n"+n);
            // If i look at the file after anything under n < 51 the file  doesn't change.
            n++;

        }
        out.flush();
        out.close();
    } catch (java.io.IOException e) {
        System.out.println("AHHHHHHHH!!!!!!");
    }
}

With the given information I can only speculate. At least it would be very helpful if you specified what type of OutputStream out is when you are calling the decrypt method. The behavior of the flush() method varies between different concrete implementations.

For example, if your output stream happens to be a CipherOutputStream , or some other stream that is connected to that type of stream, then the documentation for its flush() method states the following (important part emphasized by me):

Flushes this output stream by forcing any buffered output bytes that have already been processed by the encapsulated cipher object to be written out. Any bytes buffered by the encapsulated cipher and waiting to be processed by it will not be written out. For example, if the encapsulated cipher is a block cipher, and the total number of bytes written using one of the write methods is less than the cipher's block size, no bytes will be written out.

That certainly sounds like it could be the cause of your problem. However, as I stated, it would be very helpful to know some more details regarding your specific type of stream.

Well for what I was doing it seems that the inputstream in the decryption method was messing with the data. Instead of decrypting it when it was being read back in I decrypted it when it was being processed back out. The padding messed with it a bit too. Had to add an extra 8 bytes to the 1024*1024 code in the decryption method. If anyone cares here are the revised methods Thank you everyone for the help.

    public void encrypt(InputStream in, OutputStream out) {
    try {
        // Bytes written to out will be encrypted
       AppendableOutputStream out_append = new AppendableOutputStream(out);

       OutputStream out_c = new CipherOutputStream(out_append, ecipher);

        // Read in the cleartext bytes and write to out to encrypt
        int numRead = 0;
        int count = 0;
        int max = 1024;
        boolean first = true;

        while ((numRead = in.read(buf, 0, max)) > 0) {                 
            //System.out.println("running Total: " + count);
            count += numRead;
            // if this read puts as at less than a meg, encrypt
            if(count <= 1024*1024){
                //System.out.println("encrypted " + numRead + " of " + max +" bytes : total " + count);
                out_c.write(buf, 0, numRead);
                // last encryption pass, close buffer and fix max
                if(count == 1024*1024){
                    // fix reading 1k in case max was decreased
                    max = 1024;
                    out_c.close();
                }
                // if next read will go over a meg, read less than 1k
                else if(count + max > 1024*1024)
                    max = 1024*1024 - count;
            }
            // past the first meg, don't encrypt
            else{
                //System.out.println("processed " + numRead + " of " + max +" bytes : total " + count);
                out.write(buf, 0, numRead);
            }

        }
        out.flush();

        out.close();

    } catch (java.io.IOException e) {

        System.out.println("AHHHHHHHH!!!!!!111");

    }

}

// Movies encrypt only 1 MB 128 passes.

public void decrypt(InputStream in, OutputStream out) {
    try {
        // Bytes written to out will be decrypted
        AppendableOutputStream out_append = new AppendableOutputStream(out);
        System.out.println(ecipher.getOutputSize(1024*1024));
        OutputStream out_d = new CipherOutputStream(out_append, dcipher);

        // Read in the decrypted bytes and write the cleartext to out
        int numRead = 0;
        int count = 0;
        int max = 1024;

        while ((numRead = in.read(buf, 0, max)) > 0) {
            count += numRead;
            if(count <= ecipher.getOutputSize(1024*1024)){
                out_d.write(buf, 0, numRead);
                // last encryption pass, close buffer and fix max
                if(count == ecipher.getOutputSize(1024*1024)){
                    // fix reading 1k in case max was decreased
                    max = 1024;
                    out_d.close();
                }
                // if next read will go over a meg, read less than 1k
                else if(count + max > ecipher.getOutputSize(1024*1024))
                    max = ecipher.getOutputSize(1024*1024) - count;
            }
            // past the first meg, don't decrypt
            else{
                out.write(buf, 0, numRead);
            }

        }
        out.close();
    } catch (java.io.IOException e) {
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM