当前位置: 首页 > 知识库问答 >
问题:

如何使用文件输入和输出流从一个文件中添加和获取特定数量的字节数?

凤扬
2023-03-14

我正在处理一个类来加密/解密大文件,所以我尝试使用流而不是字节数组来避免OutOfMemory异常。在加密方法中,我将随机salt和iv添加到加密文件的开头,它工作得很好,下面是代码:

public File encryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage){
        //Create IV
        byte[] ivBytes = new byte[16];
        SecureRandom random1 = new SecureRandom();
        random1.nextBytes(ivBytes);
        IvParameterSpec iv = new IvParameterSpec(ivBytes);


        //Create the key with the salt
        SecureRandom random = new SecureRandom();
        byte[] salt = new byte[SALT_SIZE];
        random.nextBytes(salt);

        SecretKeySpec keySpec = generateAesKey(password, salt);

        //Create and Init the cipher
        Cipher c = Cipher.getInstance("AES/CBC/"+padding);
        c.init(Cipher.ENCRYPT_MODE, keySpec, iv);

        byte[] buf = new byte[8192];
        FileInputStream in = new FileInputStream(inputFile);
        FileOutputStream out = new FileOutputStream(outPutFile);
        int nread;
        int progress = 0;

        byte[] ivAndSalt = new byte[ivBytes.length + salt.length];
        System.arraycopy(ivBytes,0, ivAndSalt,0, ivBytes.length );
        System.arraycopy(salt, 0, ivAndSalt, ivBytes.length, salt.length);
        out.write(ivAndSalt);

        while((nread = in.read(buf)) != -1) {
            byte[] enc = c.update(buf, 0, nread);
            out.write(enc);
            progress++;
        }

然后尝试在解密方法中获取iv和salt,然后使用FileInputStream.GetChannel.Position():
将文件的其余部分解密为输出文件

 public File decryptFile(File inputFile, File outPutFile, String password, ProgressBar progressBar, Label progressPercentage) {
        //Create and Init Cipher
        Cipher c = Cipher.getInstance("AES/CBC/" + padding);

        FileInputStream in = new FileInputStream(inputFile);
        FileOutputStream out = new FileOutputStream(outPutFile);

        //Getting the iv and salt
        byte[] ivBytes = new byte[16];
        byte[] salt = new byte[SALT_SIZE];
        byte[] ivAndSalt = new byte[ivBytes.length+SALT_SIZE];
        in.read(ivAndSalt, 0, ivBytes.length+SALT_SIZE);
        System.arraycopy(ivAndSalt, 0, ivBytes, 0, ivBytes.length);
        System.arraycopy(ivAndSalt, ivBytes.length, salt, 0, SALT_SIZE);
        IvParameterSpec iv =new IvParameterSpec(ivBytes);
        SecretKeySpec keySpec = generateAesKey(password, salt);
        c.init(Cipher.DECRYPT_MODE, keySpec, iv);


        in.getChannel().position(ivAndSalt.length);

        int nread;
        int progress = 0;
        byte[] buf = new byte[8192];

        while((nread = in.read(buf)) != -1) {
                byte[] enc = c.update(buf, 0, nread);
                out.write(enc);
                progress++;

            /*if (enc.length / 8192 != 0)
                    System.out.println((nread*progress) + "%");*/
        }
        System.out.println("Size of out before doFinal(): " + out.getChannel().size());
        byte[] enc = c.doFinal();
        out.write(enc);
        System.out.println("Size of out after doFinal(): " + out.getChannel().size());
        return  outPutFile;
    } 

我在调用decryptFile()时没有遇到错误,但是生成的文件已损坏,这意味着解密过程中的某个地方存在问题。

共有1个答案

冷浩瀚
2023-03-14

这个问题完全是一个愚蠢的问题,在dofinal()并将enc字节数组写入输出后,我忘记关闭输入和输出流:

in.close();
out.close();
 类似资料:
  • 问题内容: 如果我有此代码,该如何保留原始文件的文件名或将其重新分配给新文件名?: 问题答案: 可以创建输入流以从文件或任何其他数据源读取。因此,将文件名附加到输入流没有任何意义。查看该类是否公开了该数据(您甚至可以使用反射来查看该类的内部)。请注意,创建者或犯了一个设计错误,没有公开此信息,或者您正在尝试制作此信息。

  • 我用Tensorflow培训了一个模型(更快的rcnn\U resnet101\U coco\U 2018\U 01\U 28)。我有一个“.pb”图形。 要制作一个冻结图,我需要输入和输出节点。 如何在图表中找到它? 我这里有完整的节点列表。 没有任何节点像Softmax,占位符,因为它在其他帖子中建议。

  • 问题内容: 这个问题已经在这里有了答案 : 7年前关闭。 可能重复: 使用jQuery输入文件的完整路径 我有以下html元素 如果我用 我只是文件名,而不是文件的完整绝对路径。有人可以告诉我如何获得完整路径吗? 问题答案: 您不能这样做-由于安全问题,浏览器将不允许这样做。尽管有解决方法,但事实是您不应该依靠这种方法。以下堆栈溢出问题与此处相关: 使用jquery输入文件的完整路径 如何从Fir

  • 问题内容: var profileImage = fileInputInByteArray; 我正在使用ajax调用将输入类型的byte[]值=输入到以api[]格式接收的Webapi输入文件。但是,我遇到了获取字节数组的困难。我期望我们可以通过File API获得字节数组。 注意:在通过ajax调用之前,我需要先将字节数组存储在变量中 问题答案: [编辑] 如上面的评论所述,尽管仍在某些UA实现

  • 本章主题 ♦ 文件对象 ♦ 文件内建函数 ♦ 文件内建方法 ♦ 文件内建属性 ♦ 标准文件 ♦ 命令行参数 ♦ 文件系统 ♦ 文件执行 ♦ 持久存储 ♦ 相关模块 本章将深入介绍Python的文件处理和相关输入输出能力。我们将介绍文件对象(它的内建函数、内建方法和属性)、标准文件,同时讨论文件系统的访问方法、文件执行,最后简洁地介绍持久存储和标准库中与文件有关的模块。 9.1 文件对象 文件对象不

  • 你已经学会了使用printf来打印变量,这非常不错,但是还需要学习更多。这个练习中你会用到fscanf和fgets在结构体中构建关于一个人的信息。在这个关于读取输入的简介之后,你会得到C语言IO函数的完整列表。其中一些你已经见过并且使用过了,所以这个练习也是一个记忆练习。 #include <stdio.h> #include "dbg.h" #define MAX_DATA 100 type