[toc]
IO流快速入门
很多初学者在学习IO流是会被繁杂的IO流相关类搞晕,更会觉得IO流看不懂,十分难。但其实,只要掌握IO流的核心概念以及使用IO流的一般 过程,就能找到IO流的一般使用方法。至于一些偏而冷门的IO流类,查阅API即可知道使用方法。
IO流的含义以及一般过程
###(1)IO流概念
当我们要在java中实现输入,输出操作时,必须按照java的IO规范,使用数据流进行输入输出操作。任何在java中表示数据源的对象最终 都需要转换为数据流的形式来读写它的数据。
IO流的几种分类方法
按照流向分为:
输入流----从外部(磁盘,网络资源)将数据读入java程序中。
输出流----从程序将输入输出到程序外部中。
按照传输数据单位分为:
字节流----数据流最小单位是字节
字符流----数据流中最小单位为字符
注意:由于不同文件的底层都是使用字节存储,所以字节流适用于各种类型的数据处理,但是字符流只适用于文本类型的文件。
###(2)IO流一般使用过程
1.从外部得到输入流对象。不同的资源对象得到的方式也不同,如果是磁盘文件直接采用FileInputStream类读取本地指定路径的文件, 如果是网络资源可能需要利用URL相关api。
2.使用字节或者字符数组将输入流对象读取。一般采用输入流对象的read方法即可,注意,当数组大小小于流的大小时,1次只会读入数组 大小数据,所以一般采用循环读入。
3.对数据数组进行逻辑处理。
4.关闭输入流。
类比输入,你能得到输出流的一般过程吗?
两种简单的IO输入输出流的使用示例
字节流--FileInputStream以及FileOutputStream
简单实现图片文件的复制(将一个图片文件复制到指定位置)
public static void main(String[] args) throws IOException {
//(1)从磁盘文件获取输入流
FileInputStream fileInputStream = new FileInputStream("./src/main/java/测试.png");
//(2)创建输出流对象,指定输出流的文件位置
FileOutputStream fileOutputStream = new FileOutputStream("./src/main/java/测试_copy.png");
//(3)创建数据流数组,存储数据
byte[] bytes = new byte[1024];
int flag;//这里设置一个flag标记观察read的执行过程
//(4)循环读入数据,并写入到输出流
while((flag=fileInputStream.read(bytes))>=0){
fileOutputStream.write(bytes);
System.out.println(flag);
}
//(5)关闭输入输出流(非常重要)
fileInputStream.close();
fileOutputStream.close();
}
字符流--FileReader以及FileWriter
使用字符流将一个文本文件的内容打印到控制台。(分析为什么不用字节流?)
public static void main(String[] args) throws IOException {
//(1)从磁盘文件获取输入流
FileReader fileReader = new FileReader("./src/main/java/k8s命令.txt");
//(2)使用字符数组接收
char[] chars = new char[2];
//(3)循环读取
while(fileReader.read(chars)>=0){
//(4)打印内容
System.out.print(new String(chars));
}
//(4)关闭输入流
fileReader.close();
}
进阶点
(1)直接使用字节流的效率十分低下,可以尝试使用缓冲流来提高效率。
(2)多种渠道输入数据,例如:尝试使用从网络URL中获取数据流。
(3)操作数据流多种方法,例如:给图片打水印。
这里给出实现水印功能的方法:
private static void addLogo(String sourceImg,String logoImage,String outputImg){
OutputStream outputStream = null;
try{
//读取源图像数据
Image sourceImage = ImageIO.read(new File(sourceImg));
BufferedImage bufferedImage = new BufferedImage(sourceImage.getWidth(null),sourceImage.getHeight(null),
BufferedImage.TYPE_INT_RGB);
//创建画笔对象,设置画布大小
Graphics2D graphics2D = bufferedImage.createGraphics();
//模糊边缘
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//绘制第一张底片
graphics2D.drawImage(sourceImage.getScaledInstance(sourceImage.getWidth(null), sourceImage
.getHeight(null), Image.SCALE_SMOOTH),0,0,null);
//读取logo数据
ImageIcon imageIcon = new ImageIcon(logoImage);
Image image = imageIcon.getImage();
//这里的异常是自定义异常,不会的可以删除相关代码或者百度一下自定义异常用法
if(image.getWidth(null)>sourceImage.getWidth(null)||
image.getHeight(null)>sourceImage.getHeight(null)){
throw new BusinessException(114,"源图片放不下水印图片");
}
//设置透明度
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,0.5f));
//绘制logo图片
graphics2D.drawImage(image,sourceImage.getWidth(null)-image.getWidth(null),
sourceImage.getHeight(null)-image.getHeight(null),null);
//结束绘制
graphics2D.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
graphics2D.dispose();
outputStream = new FileOutputStream(outputImg);
//这里要注意,类型转错会降低画质
ImageIO.write(bufferedImage,"png",outputStream);
}catch (BusinessException e1){
System.out.println(e1.getMessage());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if (null != outputStream)
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}