Java流编程实例之十--多重流使用范例

将一组信息缓冲、加密、压缩后保存到一个文件中,然后从此文件中读取该信息,经解密、解压缩后输出到屏幕。代码如下:

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.*;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * Created by test2 on 2016/9/2.
 * 真实世界的流使用范例
 */
public class RealWorldStream {
    public static void main(String[] args) {
        String srcFile = "D:\\src.txt";
        String desFile = "D:\\src.des.gz";
        makeSourceFile(srcFile);

        //密码和盐
        String password = "This is my key";
        byte[] salt = initSalt();
        //加密压缩保存
        gzipCipherFile(srcFile, desFile, password, salt);

        //解密解压,输出到屏幕
        ungzipCipherFile(desFile, password, salt);
    }

    private static void ungzipCipherFile(String desFile, String password, byte[] salt) {
        try {
            //创建密钥
            byte[] desKeyData = password.getBytes();
            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);
            char[] pbeKeyData = password.toCharArray();
            PBEKeySpec pbeKeySpec = new PBEKeySpec(pbeKeyData);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
            Cipher pbe = Cipher.getInstance("PBEWithMD5AndDES");
            pbe.init(Cipher.DECRYPT_MODE, pbeKey, paramSpec);

            BufferedInputStream bis = new BufferedInputStream(
                    new CipherInputStream(
                            new GZIPInputStream(
                                    new FileInputStream(desFile)),pbe));
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buff =new byte[1024];
            int len=0;
            while((len=bis.read(buff))!=-1){
                baos.write(buff,0,len);
            }
            baos.flush();
            String str = baos.toString("UTF-16");
            baos.close();
            bis.close();
            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    //产生加密所用的盐
    public static byte[] initSalt() {
        //实例化安全随机数
        SecureRandom random = new SecureRandom();
        //产出盐
        return random.generateSeed(8);
    }

    //将源文件进行加密压缩后保存到目标文件
    private static void gzipCipherFile(String srcFile, String desFile, String password, byte[] salt) {
        try {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));

            //创建密钥
            byte[] desKeyData = password.getBytes();
            Provider sunJce = new com.sun.crypto.provider.SunJCE();
            Security.addProvider(sunJce);
            char[] pbeKeyData = password.toCharArray();
            PBEKeySpec pbeKeySpec = new PBEKeySpec(pbeKeyData);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec);
            PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
            Cipher pbe = Cipher.getInstance("PBEWithMD5AndDES");
            pbe.init(Cipher.ENCRYPT_MODE, pbeKey, paramSpec);

            BufferedOutputStream bos = new BufferedOutputStream(
                    new CipherOutputStream(
                            new GZIPOutputStream(
                                    new FileOutputStream(desFile)), pbe));
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bis.read(buff)) != -1) {
                bos.write(buff, 0, len);
            }
            bos.flush();
            bos.close();
            bis.close();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
    }

    //创建一个程序中用来执行的源文件
    private static void makeSourceFile(String srcFile) {
        File file = new File(srcFile);
        String str = "Today is a good day. 今天天气很好。";
        try {
            //使用JAVA内部的编码标准UTF-16来进行char到byte的编码转换
            byte[] bytes = str.getBytes("UTF-16");

            //写入文件
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            FileOutputStream fos = new FileOutputStream(file);
            byte[] buff = new byte[1024];
            int len = 0;
            while ((len = bais.read(buff)) != -1) {
                fos.write(buff, 0, len);
            }
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

如果你已经阅读过本博客的其他文章,理解这一段代码也没有任何问题了。Java的流就是这样使用的,入手稍微有一点困难,但是熟悉之后很容易写出功能强大的代码。

本系列的其他文章:
http://blog.csdn.net/logicteamleader/article/details/52434840
http://blog.csdn.net/logicteamleader/article/details/52463765
http://blog.csdn.net/logicteamleader/article/details/52556480
http://blog.csdn.net/logicteamleader/article/details/52557261
http://blog.csdn.net/logicteamleader/article/details/52557329
http://blog.csdn.net/logicteamleader/article/details/52693597
http://blog.csdn.net/logicteamleader/article/details/52724749
http://blog.csdn.net/logicteamleader/article/details/53292099
http://blog.csdn.net/logicteamleader/article/details/53405061
http://blog.csdn.net/logicteamleader/article/details/53405182

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值