java实现文件加密解密多种方法

 更新时间:2023年07月31日 09:50:05   作者:follow_me!  
这篇文章主要给大家介绍了关于java实现文件加密解密多种方法的相关资料, Java支持多种加密解密算法,常用的有DES、AES、RSA等,需要的朋友可以参考下

一、对于文件流读写取的方式对比:

inputStream.read()与OutputStream.write()单字节读取,效率低下
inputStream.read(new byte[80*1024])与OutputStream.write(new byte[80*1024])固定数组读取,经测试数组增加到80k左右性能最佳
nputStream.read(inputStream.available()) 与OutputStream.write(inputStream.available())按文件大小一次性读取,如文件过大有内存溢出风险
BufferedInputStream.read()与BufferedOutputStream.write()默认有一个8K的缓存数组

二、循环每个字节加解密(此方法效率最低):

1.通过inputStream.read()单字节加密,inputStream.read()返回的是一个字节的内容(0-255之间的数字),可直接异或加密:

    @PostMapping("/swlUpload")
    public void swlUpload(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        //FileInputStream inputStream = new FileInputStream((File) file);
        byte[] b = new byte[1024];
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        int  swl = 0;
        while((swl=inputStream.read())!=-1){
            //System.out.println(b);
            bufferedOutputStream.write(swl^9527);
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
    }

2.通过inputStream.read()单字节解密:

    @PostMapping("/swlDownload")
    public void swlDownload(HttpServletResponse response) throws IOException {
        File f2= new File("D:\\108B计划.xlsx");
        boolean exists = f2.exists();
        FileInputStream inputStream = new FileInputStream(f2);
        //byte[] b = new byte[1024];
        String filePath = "108B计划.xlsx";
        //6.1清除buffer缓存
        response.reset();
        response.setContentType("application/octet-stream;charset=UTF-8");
        //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8"));
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Expires", " 0");
        ServletOutputStream outputStream = response.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        int swl = 0;
        while((swl = inputStream.read())!=-1){
            bufferedOutputStream.write(swl^9527);
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
    }

三、加载整个文件加解密(效率快,有内存溢出风险):

1.通过inputStream.read(bytes) 加载整个文件,inputStream.read(bytes)返回bytes大小的字节,放入bytes数组中,循环异或加密:

    @PostMapping("/swlUpload")
    public void swlUpload(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        //FileInputStream inputStream = new FileInputStream((File) file);
        byte[] b = new byte[8*1024];
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        //一、整体io读取、循环加密
        long l = System.currentTimeMillis();
        log.info(String.valueOf(System.currentTimeMillis()));
        int  swl = 0;
        byte[] bytes = new byte[inputStream.available()];
        while((inputStream.read(bytes))!=-1){
            //System.out.println(b);
            for(int i=0;i<bytes.length;i++){
                bufferedOutputStream.write(bytes[i]^9527);
            }
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
        log.info(String.valueOf(System.currentTimeMillis()));
        log.info(String.valueOf(System.currentTimeMillis()-l));
    }

2.通过inputStream.read(bytes) 加载整个文件解密:

    @PostMapping("/swlDownloadAll")
    public void swlDownloadAll(HttpServletResponse response) throws IOException {
        File f2= new File("D:\\84333c1377d99d970a0984049db926ae.mp4");
        boolean exists = f2.exists();
        FileInputStream inputStream = new FileInputStream(f2);
        //byte[] b = new byte[1024];
        String filePath = "84333c1377d99d970a0984049db926ae.mp4";
        //6.1清除buffer缓存
        response.reset();
        response.setContentType("application/octet-stream;charset=UTF-8");
        //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8"));
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Expires", " 0");
        ServletOutputStream outputStream = response.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        long l = System.currentTimeMillis();
        log.info(String.valueOf(System.currentTimeMillis()));
        int swl = 0;
        byte[] bytes = new byte[inputStream.available()];
        while((inputStream.read(bytes))!=-1){
            for(int i=0;i<bytes.length;i++){
                bufferedOutputStream.write(bytes[i]^9527);
            }
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
        log.info(String.valueOf(System.currentTimeMillis()));
        log.info(String.valueOf(System.currentTimeMillis()-l));
    }

四、小数组加载文件加解密(效率快,无内存溢出风险)【推荐】:

1.通过inputStream.read(b) 加载整个文件,inputStream.read(b)返回b大小的字节,放入b数组中,循环异或加密:

    @PostMapping("/swlUploadArray")
    public void swlUploadArray(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        InputStream inputStream = file.getInputStream();
        //FileInputStream inputStream = new FileInputStream((File) file);
        byte[] b = new byte[8*1024];
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:\\"+originalFilename));
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        //三、小数组循环io读取、循环加密
        long l = System.currentTimeMillis();
        log.info(String.valueOf(System.currentTimeMillis()));
        while((inputStream.read(b))!=-1){
            //System.out.println(b);
            for(int i=0;i<b.length;i++){
                bufferedOutputStream.write(b[i]^9527);
            }
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
        log.info(String.valueOf(System.currentTimeMillis()));
        log.info(String.valueOf(System.currentTimeMillis()-l));
    }

2.通过inputStream.read(b) 加载整个文件解密:

    @PostMapping("/swlDownloadArray")
    public void swlDownloadArray(HttpServletResponse response) throws IOException {
        File f2= new File("D:\\84333c1377d99d970a0984049db926ae.mp4");
        boolean exists = f2.exists();
        FileInputStream inputStream = new FileInputStream(f2);
        byte[] b = new byte[8*1024];
        String filePath = "84333c1377d99d970a0984049db926ae.mp4";
        //6.1清除buffer缓存
        response.reset();
        response.setContentType("application/octet-stream;charset=UTF-8");
        //response.setHeader("Content-Disposition", "inline; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        //response.setHeader("Content-Disposition", "attachment; filename="+ new String(filePath.getBytes("UTF-8"), "ISO-8859-1"));// 定义文件名
        response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(filePath, "UTF-8"));
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Expires", " 0");
        ServletOutputStream outputStream = response.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        long l = System.currentTimeMillis();
        log.info(String.valueOf(System.currentTimeMillis()));
        int swl = 0;
        while((inputStream.read(b))!=-1){
            for(int i=0;i<b.length;i++){
                bufferedOutputStream.write(b[i]^9527);
            }
        }
        //6.2用来刷新缓冲区,刷新后可以再次写出
        bufferedOutputStream.flush();
        inputStream.close();
        bufferedOutputStream.close();
        log.info(String.valueOf(System.currentTimeMillis()));
        log.info(String.valueOf(System.currentTimeMillis()-l));
    }

五、解决小数组读取文件流后,office文档打开异常的问题:

注意看下面的代码:

原因:这是文档最后一次读取文件,剩余的文件流不足b.length造成的,不足时会在数组中补0,造成上传后的文件与原文件有出入。解决方案1:采用byte[] bytes = new byte[inputStream.available()];解决方案2(推荐):

        int j;
        while((j=(inputStream.read(b)))!=-1){
            for(int i=0;i<j;i++){
                bufferedOutputStream.write(b[i]^9527);
            }
        }

总结 

到此这篇关于java实现文件加密解密的文章就介绍到这了,更多相关java文件加密解密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • RSA加密算法java简单实现方法(必看)

    RSA加密算法java简单实现方法(必看)

    下面小编就为大家带来一篇RSA加密算法java简单实现方法(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • java中hashmap容量的初始化实现

    java中hashmap容量的初始化实现

    这篇文章主要介绍了java中hashmap容量的初始化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • 详解用Kotlin写一个基于Spring Boot的RESTful服务

    详解用Kotlin写一个基于Spring Boot的RESTful服务

    这篇文章主要介绍了详解用Kotlin写一个基于Spring Boot的RESTful服务 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • JAVA时间存储类Period和Duration使用详解

    JAVA时间存储类Period和Duration使用详解

    这篇文章主要为大家介绍了JAVA时间存储类Period和Duration使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • SpringBoot整合Milvus的实现

    SpringBoot整合Milvus的实现

    本文主要介绍了SpringBoot整合Milvus的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 关于Java虚拟机HotSpot

    关于Java虚拟机HotSpot

    这篇文章主要介绍了关于Java虚拟机HotSpot,在Java类中的一些方法会被由C/C++编写的HotSpot虚拟机的C/C++函数调用,不过由于Java方法与C/C++函数的调用约定不同,所以并不能直接调用,需要JavaCalls::call()这个函数辅助调用,下面我们来看看文章对内容的具体介绍
    2021-11-11
  • RxJava2 Scheduler使用实例深入解析

    RxJava2 Scheduler使用实例深入解析

    这篇文章主要为大家介绍了RxJava2 Scheduler使用实例深入解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • JAVA日常开发中读写XML的方法详解

    JAVA日常开发中读写XML的方法详解

    这篇文章主要介绍了JAVA日常开发中读写XML的相关资料,详细讲解了在Java中如何使用DOM(文档对象模型)和SAX(简单API for XML)两种方式读取XML文件,以及如何使用DOM和JAXB(Java Architecture for XML Binding)两种方式写入XML文件,需要的朋友可以参考下
    2024-12-12
  • SpringBoot+JavaMailSender实现腾讯企业邮箱配置

    SpringBoot+JavaMailSender实现腾讯企业邮箱配置

    这篇文章主要介绍了SpringBoot+JavaMailSender实现腾讯企业邮箱配置,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Springboot中使用拦截器、过滤器、监听器的流程分析

    Springboot中使用拦截器、过滤器、监听器的流程分析

    Javaweb三大组件:servlet、Filter(过滤器)、 Listener(监听器),这篇文章主要介绍了Springboot中使用拦截器、过滤器、监听器的流程分析,感兴趣的朋友跟随小编一起看看吧
    2023-12-12

最新评论