文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

outputStream(输出流)转inputstream(输入流)以及输入流如何复用

2023-10-21 08:58

关注

目录

需求:

通过MultipartFile 上传文件到文件服务器,上传前要把文件转为pdf格式进行上传,并生成文件摘要用来验证服务器中的文件是否被篡改。

准备:

需要涉及到 inputstream(输入流)或outputStream(输出流)要使用两次 。
一、如果该文件本身就是pdf格式则直接进行上传。第一次是通过输入流去上传文件;第二次是通过输入流去生成文件摘要。

二、如果该文件不是pdf则需要工具类把文件转为pdf再上传。转pdf的工具类 返回的为outputStream(输出流)。上传的工具类以及生成摘要的工具类则需要inputstream(输入流)。
则需要把输出流进行转化变为输入流,然后再第一次是通过输入流去上传文件;第二次是通过输入流去生成文件摘要

注:流读过一次就不能再读了,而InputStream对象本身不能复制

文件、流之间的转换

MultipartFile 转 inputstream(输入流)

 byte [] byteArr=file.getBytes(); InputStream inputStream = new ByteArrayInputStream(byteArr);

outputStream(输出流)转为 inputstream(输入流)

 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); InputStream inputStream2 = new ByteArrayInputStream(outputStream.toByteArray());

inputstream (输入流)转 ByteArrayOutputStream

 //InputStream 转 ByteArrayOutputStream //获取到一个inputstream后,可能要多次利用它进行read的操作。由于流读过一次就不能再读了,而InputStream对象本身不能复制,而且它也没有实现Cloneable接口   public static ByteArrayOutputStream cloneInputStream(InputStream input) {        try {            ByteArrayOutputStream baos = new ByteArrayOutputStream();            byte[] buffer = new byte[1024];            int len;            while ((len = input.read(buffer)) > -1) {                baos.write(buffer, 0, len);            }            baos.flush();            return baos;        } catch (IOException e) {            e.printStackTrace();            return null;        }    }

MultipartFile 文件直接转输入流上传和生成摘要

通过file 转字节数组,因为流不能重复读,所以要new成两个输入流。

 //获取并生成以pdf为后缀的文件名称  String fileName = StringUtils.substringBeforeLast(originalFilename,".");   fileName = fileName +".pdf";   //如果上传的为pdf 则直接进行上传 不需要转换   if(originalFilename.endsWith(".pdf")){       //文件转字节数组       byte [] byteArr=file.getBytes();       //输入流1       InputStream inputStream = new ByteArrayInputStream(byteArr);       //输入流2       InputStream inputStream2 = new ByteArrayInputStream(byteArr);       //文件上传       url = CephUtils.uploadInputStreamReturnUrl("/" + Constants.CEPH_BUCK_NAME, fileName, inputStream);       //生成文档hash 摘要       hash = FileHahUtil.hashAbstractByInputStream(inputStream2);    }

MultipartFile 文件需要转为pdf 再进行上传和生成摘要

 //转换为pdf 后的输出流 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); //原文件 byte [] byteArr=file.getBytes();  InputStream inputStream = new ByteArrayInputStream(byteArr);  //要转为pdf 文档  Word2PdfUtil.convert2PdfStream(inputStream,outputStream);  //输出流转输入流  ByteArrayOutputStream baosPdf = (ByteArrayOutputStream) outputStream ;  InputStream inputStream2 = new ByteArrayInputStream(baosPdf.toByteArray());  //inputStream 只能用来读取一次  所以进行copy一个新的 用来生成摘要  InputStream inputStream3 = new ByteArrayInputStream(baosPdf.toByteArray());  //生成文档hash 摘要  hash = FileHahUtil.hashAbstractByInputStream(inputStream3);  //上传文件  url = fileService.uploadFileByInputStream(inputStream2,fileName);

文件上传源码

 //文件上传(文档转pdf)    @ApiOperation(value = "文件上传(文档转pdf)", produces = "application/json")    @ApiResponses(value = {@ApiResponse(code = 200, message = "文件上传(文档转pdf)")})    @PostMapping(value = "/uploadWordFile")    public BaseVo<Contract> uploadWordFile(HttpServletRequest request, MultipartFile file, HttpServletResponse response){        long startTimeTotal = System.currentTimeMillis();        BaseVo<Contract> baseVo = new BaseVo<Contract>();        baseVo.setCodeMessage(CodeConstant.FAILURE_CODE);        try {            if(null != file){                String originalFilename = file.getOriginalFilename();                //文件上传后返回的地址                String url = "";                //文件摘要的hash值                String hash = "";                if (!originalFilename.endsWith(".docx") && !originalFilename.endsWith(".doc") && !originalFilename.endsWith(".pdf")) {                    //上传的文件格式不支持                    baseVo.setMessage("暂不支持当前文件格式上传!");                }else {                    //生成新的文件名称                    String fileName = StringUtils.substringBeforeLast(originalFilename,".");                    fileName = fileName +".pdf";                    //如果上传的为pdf 则直接进行上传 不需要转换                    if(originalFilename.endsWith(".pdf")){                        byte [] byteArr=file.getBytes();                        InputStream inputStream = new ByteArrayInputStream(byteArr);                        InputStream inputStream2 = new ByteArrayInputStream(byteArr);                        url = CephUtils.uploadInputStreamReturnUrl("/" + Constants.CEPH_BUCK_NAME, fileName, inputStream);                        //生成文档hash 摘要                        hash = FileHahUtil.hashAbstractByInputStream(inputStream2);                    }else {                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();                        byte [] byteArr=file.getBytes();                        InputStream inputStream = new ByteArrayInputStream(byteArr);                        //要转为pdf 文档                        Word2PdfUtil.convert2PdfStream(inputStream,outputStream);                        ByteArrayOutputStream baosPdf = (ByteArrayOutputStream) outputStream ;                        InputStream inputStream2 = new ByteArrayInputStream(baosPdf.toByteArray());                        //inputStream 只能用来读取一次  所以进行copy一个新的 用来生成摘要                        InputStream inputStream3 = new ByteArrayInputStream(baosPdf.toByteArray());                        //生成文档hash 摘要                        hash = FileHahUtil.hashAbstractByInputStream(inputStream3);                        url = fileService.uploadFileByInputStream(inputStream2,fileName);                        baosPdf.close();                        inputStream2.close();                        outputStream.close();                    }                    if(StringUtils.isNotEmpty(url)){                        // 保存合同信息 到数据库                        Contract contract = new Contract();                        //随机字符串                        String str = StringUtils.replace(UUID.randomUUID().toString(), "-", "");                        contract.setCode(CodeGenerator.getLongCode(str));                        contract.setContractUrl(url);                        contract.setName(fileName);                        contract.setHashCode(hash);                        contractService.saveOrUpdate(contract);                        //返回合同信息                        baseVo.setData(contract);                        baseVo.setCodeMessage(CodeConstant.SUCCESS_CODE);                    }                }            }        }catch (Exception e){            e.printStackTrace();            MeUtils.info("uploadFile error",e);        }        long endTimeTotal = System.currentTimeMillis();        MeUtils.info("uploadFile total time:" + (endTimeTotal - startTimeTotal));        return baseVo;    }

生成文件摘要用的是文件hash 摘要算法中的SHA-256,docx或doc转pdf用的是aspose 中提供的方法,文件上传用的Ceph分布式文件系统中的。这里暂时不详细介绍,只贴一些代码。后面再出详细文档,以及开发中遇到的坑。

文件hash 摘要算法
     public static String hashAbstractByInputStream(InputStream fis) throws Exception {        String sha256 = null;        try {            MessageDigest md = MessageDigest.getInstance("SHA-256");            byte buffer[] = new byte[1024];            int length = -1;            while ((length = fis.read(buffer, 0, 1024)) != -1) {                md.update(buffer, 0, length);            }            byte[] digest = md.digest();            sha256 = byte2hexLower(digest);        } catch (Exception e) {            e.printStackTrace();            throw new Exception("生成文件hash值失败");        } finally {            try {                if (fis != null) {                    fis.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return sha256;    }
docx或doc转pdf
public static void convert2PdfStream(InputStream inputStream, ByteArrayOutputStream outputStream) {        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生            return;        }        try {            long old = System.currentTimeMillis();            Document doc = new Document(inputStream);            //insertWatermarkText(doc, "测试水印"); //添加水印            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();            pdfSaveOptions.setSaveFormat(SaveFormat.PDF);            // 设置3级doc书签需要保存到pdf的heading中            pdfSaveOptions.getOutlineOptions().setHeadingsOutlineLevels(3);            // 设置pdf中默认展开1级            pdfSaveOptions.getOutlineOptions().setExpandedOutlineLevels(1);            //doc.save(outputStream, pdfSaveOptions);            // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,EPUB, XPS, SWF 相互转换            doc.save(outputStream, SaveFormat.PDF);            long now = System.currentTimeMillis();            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时        } catch (Exception e) {            e.printStackTrace();        }    }
文件上传
     public static String uploadInputStreamReturnUrl(String bucketName, String fileName, InputStream input) {//        String path = bucketName + timeSuffix();        PutObjectResult putObjectResult = conn.putObject(bucketName, fileName, input, new ObjectMetadata());        String cephUrl = ENDPOINT + bucketName + "/" + fileName;        return cephUrl;    }

来源地址:https://blog.csdn.net/xuxu_study/article/details/129992752

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯