io流的学习和应用
- io流的基础知识和基础语法
1.1 File类学习–完成
Java.io包的File类,File类用于目录和文件的创建、删除、遍历等操作,但不能用于文件的读写。
1.2 inputstream学习–完成
什么是输入流:输入流(InputStream)只能读取数据,不能写入数据。
1.3 OutputStream学习–完成
什么是输出流:输出流(OutputStream)只能写入数据,不能读取数据。
1.4 java的缓冲流–完成
为什么使用缓冲流:上面已经解释了流的操作实际上就是对磁盘的操作,正常流的操作是读取到磁盘一个数据字节就会写入或者写出一个字节,每次与磁盘的交互
都是需要一定时间比较耗时,使用缓冲流,一次性读取固定字节量的数据返回,可以减少磁盘交互,失使效率提升,注意需要控制每次读取的字节数量因为如果读取的
字节量太大会导致长时间占用磁盘使用,会影响整个服务的性能;
1.5 字符流–了解下就行
实战代码:
/**
* 〈io的基础语法〉
*
* @author 莉莉
* @create 2021/07/25
* @since 1.0.0
*/
public class BaseIo {
/**
* io的基础语法分为3个部分
* 1.文件的读取
* 2.文件流的读取
* 3.文件流的输出
*/
//文件的读取(File):
// Java.io包的File类,File类用于目录和文件的创建、删除、遍历等操作,但不能用于文件的读写。
public static File fileTest(){
//基础用法读取文件
String url = "";
File file = new File(url);//有多种创建,这个是最常用,其余的(有好几个构造方法)只是简单了解了一下
System.out.println(file.getName());//获取文件名称
System.out.println(file.getParent());//获取父文件名称
System.out.println(file.getAbsolutePath());//获取全路径
System.out.println(file.length());//获取文件大小
System.out.println(file.isFile());//判断是否是文件
System.out.println(file.isDirectory());//判断是否是文件夹
try {
System.out.println(file.createNewFile());//创建文件夹
System.out.println(file.mkdirs());//文件夹不存在时是创建
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
流的使用 输入输出流,缓冲流
。
public void downloadExecel(HttpServletResponse response, HttpServletRequest request) throws Exception {
InputStream in = null;
OutputStream os = null;
BufferedOutputStream bos = null;
ByteArrayOutputStream stream = null;
try {
response.setHeader("content-Type","application/vnd,ms-excel:utf-8");
response.setHeader("Content-disposition","attachment; filename="+ URLEncoder.encode("测试模板.xls","utf-8"));
in = Thread.currentThread().getContextClassLoader().getResourceAsStream("template/模板.xls");
if (in == null){
return;
}
byte[] bytes = new byte[1024];
int len;
os = response.getOutputStream();
//这个是正常的数据流输出
// while ((len = in.read(bytes)) > 0){
// os.write(bytes,0,len);
// }
//这个是使用缓冲流
bos = new BufferedOutputStream(os);
while ((len = in.read(bytes)) > 0){
bos.write(bytes,0,len);
}
//获取流的方法
stream = new ByteArrayOutputStream();
while ((len = in.read())>0){
stream.write(bytes,0,len);
}
byte[] resultBytes = stream.toByteArray();
bos.flush();
os.flush();
}finally {
if (in != null){
in.close();
}
if (os != null){
os.close();
}
if (bos != null){
bos.close();
}
if (stream != null){
stream.close();
}
}
}
- io知识升级学习
2.1 PDF的数据传输与处理
主要使用的工具为IText
操作的一个流程
用iText生成PDF文档需要5个步骤:
①建立com.itextpdf.text.Document对象的实例。
Document document= new Document();
②建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
PDFWriter.getInstance(document,new FileOutputStream(“ITextTest.pdf”));
③打开文档。
document.open();
④向文档中添加内容。
document.add(newParagraph(“IText Test”));
⑤关闭文档。
document.close();
通过上面的5个步骤,就能产生一个ITextTest.PDF的文件,文件内容为"ITextTest"。
当然具体还有涉及到格式的font,cell,还有水印,页脚页眉的一些设置这个可以参考下网上的一些资料进行编写PDF,
同时还有二维码(QRCodeWriter),图片(image工具)的应用也是可以使用这个工具进行操作的,这里就不做案例展示了
因为工作上只用过几次,一般都会有模板工具进行处理(ireport等),但是一些简单的PDF处理,参考网上的一些资料是可以搞定的
后期高级功能学习的时候会在打印微服务通过工具包的形式编写一下;
2.2 Excel表单的数据传输与处理
这里主要有两个表单处理的工具第一个是easyExcel和HSSFWorkbook、XSSFWorkbook、CsvReader,但是如果直接使用的话会有很多坑
有一个我处理过的问题就是如果读取百万行的数据时(可能因为格式的问题默认为百万行),因为这两个工具在
解析文件的时候也是按row去进行读取的(感兴趣的话可以去看下源码解析),这个底层也是数据流的读取,这样长时间占用内存会对服务去造成巨大压力(请求多的话会宕机:因为吃内存oom)
同时也会出现相应超时的情况,所以一般如果想要正常使用这个工具的话需要做拦截先判断下这个文件的行数,进行行数和文件大小管控才能友好的继续使用;
在微服务print组块会进行aop拦截处理的展示 - 跨服务调用的处理
3.1 数据流直接返回处理(response)
3.2 放入参数中处理
其实在实际开发的过程中微服务间的调用需要在请求中获取返回的数据流,第一种就是直接将流放入固定参数中,调用返回时直接按正常的取出参数就可以,第二种是将文件放到response中,如果还需要对返回的数据流进行处理那么就需要取出数据流进行操作