最近在研究文件的加密解密(AES),但是在文件流的读写方面不是很熟。请熟悉的朋友帮看看下面的异常是怎么回事,谢谢啦
protected static byte[] readbyte(InputStream stream) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;

while ((length = stream.read(buffer)) > 0) {
baos.write(buffer, 0, length);         // 异常
                            }
return baos.toByteArray(); } catch (Exception exception) {
return exception.getMessage().getBytes();
}
}
当传入大文件的时候会出现内存溢出异常:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

解决方案 »

  1.   

    额~还是把调用的代码也一起贴出来吧:
    // 加密文件
    public static void EncryptFile(String pwd, File fileIn, File fileOut)
    throws Exception {
    try {
    // 读取文件
    FileInputStream fis = new FileInputStream(fileIn);
    byte[] bytIn = readbyte(fis);
    // AES加密
    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    kgen.init(128, new SecureRandom(pwd.getBytes()));
    SecretKey skey = kgen.generateKey();
    byte[] raw = skey.getEncoded();
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    // 写文件
    byte[] bytOut = cipher.doFinal(bytIn);
    FileOutputStream fos = new FileOutputStream(fileOut);
    InputStream sbs = new ByteArrayInputStream(bytOut);
    fos.write(readbyte(sbs));
    fos.close();
    fis.close();
    } catch (Exception e) {
    throw new Exception(e.getMessage());
    }
    }
    // 读取InputStream转换为byte函数 ----2011-02-23 by hrg
    protected static byte[] readbyte(InputStream stream) {
    try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;

    while ((length = stream.read(buffer)) > 0) {
    baos.write(buffer, 0, length);
    }
    return baos.toByteArray(); } catch (Exception exception) {
    return exception.getMessage().getBytes();
    }
    }
    现在传入小文件没事,大一点的(比如100M以上)就报内存溢出了。高手来帮看一下该如何改撒!
      

  2.   

    就是内存溢出。虚拟机运行的时候,是有内存上限的,默认的应该是几十兆。但是你可以手动设置的。
    java name -Xms100m -Xmx800m
    -Xms设置的是虚拟机初始化name程序时的内存分配,这里是100m,-Xmx是name程序可获得的最大的内存,这里是800m。
    如果你是使用IDE的话,就更方便,可以设置工程属性中的运行参数,将-Xms100m -Xmx800m添加上去,
    比如,使用NetBean,在项目列表中选中某个工程,右击--属性,在左边的类别中选择--运行,将-Xms100m -Xmx800m添加在VM选项中。
      

  3.   

    不要用ByteArrayOutputStream/ByteArrayOutputStream, 这两个类都会把数据保存在内存中。可以直接用FileOutputStream/FileInputStream
      

  4.   

    我百度了下,发现一个帖子,看看你可以参考一下不http://www.blogjava.net/midstr/archive/2008/08/30/225744.html
      

  5.   


    对文件流不是很懂,能稍微说一下用fileInputStream该怎么改吗?
      

  6.   


        public static void EncryptFile(String pwd, File fileIn, File fileOut)
                throws Exception {
            try {
                // ????
                FileInputStream fis = new FileInputStream(fileIn);

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(128, new SecureRandom(pwd.getBytes()));
                SecretKey skey = kgen.generateKey();
                byte[] raw = skey.getEncoded();
                SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                // ???
                
    FileOutputStream fos = new FileOutputStream(fileOut);

    byte[] buffer = new byte[1024];
                int length = 0;
                while ((length = fis.read(buffer)) > 0) {
                    byte[] bytOut = cipher.doFinal(buffer, 0, length);
    fos.write(bytOut, 0, byteOut.length);
                }

                fos.close();
                fis.close();
            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
        }没验证过是不是正确
      

  7.   

    谢谢~这样可以加密了 。可是解密的时候会出异常:
    Exception in thread "main" java.lang.Exception: Given final block not properly padded
    网上找了蛮多方法都无能为力…… 莫名其妙啊!
      

  8.   


    OK 解决了! 现在在考虑跟C++互解的问题。C这一端是要根据算法自己写的。请问是不是要知道java这端AES是使用哪种工作模式才能实现互解呀? 我的代码是属于哪种模式?