首页 > 其他分享 >outputStream(输出流)转inputstream(输入流)以及输入流如何复用

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

时间:2024-03-23 11:46:06浏览次数:26  
标签:文件 outputStream inputstream new pdf InputStream 上传 输入

https://blog.csdn.net/xuxu_study/article/details/129992752


文件、流之间的转换
MultipartFile 转 inputstream(输入流)
outputStream(输出流)转为 inputstream(输入流)
inputstream (输入流)转 ByteArrayOutputStream
MultipartFile 文件直接转输入流上传和生成摘要
MultipartFile 文件需要转为pdf 再进行上传和生成摘要
文件上传源码
文件hash 摘要算法
docx或doc转pdf
文件上传
需求:
通过MultipartFile 上传文件到文件服务器,上传前要把文件转为pdf格式进行上传,并生成文件摘要用来验证服务器中的文件是否被篡改。

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

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

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

文件、流之间的转换
MultipartFile 转 inputstream(输入流)
byte [] byteArr=file.getBytes();
InputStream inputStream = new ByteArrayInputStream(byteArr);
1
2
outputStream(输出流)转为 inputstream(输入流)
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
InputStream inputStream2 = new ByteArrayInputStream(outputStream.toByteArray());
1
2
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;
}
}


17
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 摘要算法
/**
* 生成文件hashCode值
*/
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();
}
}


文件上传
/**
* 上传InputStream文件
*
* @param bucketName
* @param fileName
* @param input
*/
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;
}

文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览142764 人正在系统学习中
————————————————

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/xuxu_study/article/details/129992752

标签:文件,outputStream,inputstream,new,pdf,InputStream,上传,输入
From: https://www.cnblogs.com/sdgtxuyong/p/18090921

相关文章

  • 输入8个整数放入一维数组w中,输出交换前的数组,找出其中的最大数和最小数并将他们分别与
    #include<stdio.h>intmain(){intw[8];inti,maxIndex=0,minIndex=0,temp;//用户输入8个整数printf("请输入8个整数:");for(i=0;i<8;i++){scanf("%d",&w[i]);}//假设第一个元素为最大和最小值......
  • 软件测试--设计函数实现输入日期显示星期几
    1.划分等价类:2.运用等价类划分法设计测试用例3.源程序代码1importjava.text.ParseException;2importjava.text.SimpleDateFormat;3importjava.util.Calendar;4importjava.util.Date;5importjava.util.Scanner;67publicclasstest1{8......
  • Java 基础IO 输入输出流3
    1.了解IO一个输入流用于从源读取数据。并且,输出流用于将数据写入目标。System.out是一种输出流。--向显示器控制台输出-字节流JavaInputStream类JavaOutputStream类字符流JavaReader类JavaWriter类2.InputStream输入文件读取-字节读取-序列化读取3.OutputStr......
  • 【C语言】格式化输入/输出
    C语言格式化输入、输出简介使用printf函数格式化输出整数转换说明符浮点数转换说明符字符串转换说明符其他转换说明符字段宽度和精度控制标志转义符使用scanf函数格式化输入扫描设置(scanset)scanf函数的问题简介Streamsprovidecommunication......
  • 磁盘-输入输出-总线
    磁盘磁盘分为磁道和扇区磁盘的存取时间=寻道时间+等待时间(寻道时间耗时比等待时间长)寻道时间是磁头寻找到磁道的时间,等待时间就是等待读写的扇区转到磁头的时间寻道有以下调度算法先来先服务FCFS:就是按请求先来先服务最短寻道时间优先SSTF:先去离当前磁头最近的磁道(有......
  • MT2492 16V输入 600KHz 2A DCDC同步降压转换器 航天民芯一级代理
    深圳市润泽芯电子有限公司为航天民芯一级代理描述  MT2492是一款完全集成的高效率产品2A同步整流降压变换器。MT2492在一段时间内高效运行宽输出电流负载范围。该设备提供两种工作模式,即PWM控制和PFM模式切换控制在更宽的工作范围内实现高效率加载。MT2492需要最少数量的......
  • 输入日期显示星期几
    #include<stdio.h>#include<stdlib.h>intisLeapYear(intyear){if((year%4==0&&year%100!=0)||year%400==0){return1;//是闰年}else{return0;//不是闰年}}intgetDaysInMonth(intyear,intmonth)......
  • fileinputstream的主要用法
    importjava.io.*;publicclassMain{publicstaticvoidmain(String[]args)throwsIOException{//字节流读数据//FileInputStreamfileInputStream=newFileInputStream("C:\\\\Users\\\\31339\\\\Desktop\\\\新建文件夹(7)\\\......
  • 复试C++15真题_程序设计2_递归_输入字符串倒序转整形
    编写一个递归函数,功能为:输入一个字符串,输出一个整数值。例如输入 "1a2xcz34,5a!6" , 输出654321。一开始想不明白怎么写递归,于是我写了迭代的函数。意识到,递归的过程就是实现了迭代的循环,而循环内的操作本质没有太大差别。于是就写出来了:#include<iostream>usingnam......
  • 解决el-input无法输入的问题和表单验证失败问题
    el-input无法输入的问题和表单验证失败问题原因1、el-input组件没有绑定双向响应式数据(v-model)解决方案:在data中定义一个变量,然后在el-input组件中使用v-model进行双向数据绑定,这样子就会解决el-input组件无法输入的问题了。原因2、组件嵌套太深(具体原因不清楚,只知......