赞
踩
目录
Java中I/O操作主要是指使用java.io
包下的内容,进行输入、输出操作。I 是输入(input)也叫做读取数据,O是输出(Output)也叫做作写出数据。
IO流根据数据的流向分为输入流和输出流
输入流 :把数据从其他设备读入到内存中的流
输出流 :把数据从内存中写出到其他设备的流
根据数据类型可以分为字节流和字符流
字节流 :以字节为单位,读写数据的流。
字符流 :以字符为单位,读写数据的流
这两种分类正好和Java中各种流的四个顶级父类相对应,如下
输入流 | 输出流 | |
---|---|---|
字节流 | 字节输入流 InputStream | 字节输出流 OutputStream |
字符流 | 字符输入流 Reader | 字符输出流 Writer |
因为四种流的子类功能大致相同,所以这里用一个表格来展示四种流的常用子类
| 字节输入流 | 字节输出流 | 字符输入流: | 字符输出流: |
超类 | InputStream | OutputStream | Reader | Writer |
常用子类 | FileInputStream 构造方法 FileInputStream(File file) FileInputStream(String path) | FileOutputStream 构造方法: FIleOutputStream(File file,boolean append) FIleOutoutStream(String name,boolean append) 后面的参数不写默认为false,false为覆盖,true为拼接
| FileReader 构造方法: FileReader(File file) FileReader(String path) | FileWriter 构造方法 FileWriter(File file, boolean append) FileWriter(String fileName, boolean append) 后面的参数不写默认为false,false为覆盖,true为拼接 |
常用方法 | read 读字节 read() 读单个字节,返回读到的字节 read(byte[] bytes)读取一个字节数组 一次读一个固定长度的字节数组,将读取到的内容存到bytes中,返回读取的个数 | write写字节
| read 读字符 read()读单个字符 read(char[] chars)读取一个字符数组,,一次读取一个固定长度的字符数组,将读取到的内容存到chars中,返回读取的个数 | write 写字符 write(char[] chs)写字符数组 write(char[] int start,int length)写字符数组的一部分 flush()刷新,字符输出流必须刷新,不刷新数据不进入到数据墓地 close()关闭资源,在关闭前,会自动刷新一次 |
注意:
1、输入流以字节输入流为例,使用read()方法 读字节,读完后,会返回-1,可以一次为文件读完与否的依据
2、万物皆字节,所以使用字节流保证了数据的安全性,而使用字符流会造成字符丢失的情况,建议文本使用字符流读取,非文本使用字节流读取
3、输出流,以字节输出流为例,输出流往外写东西需要一个文件作为实例化参数,如果存在直接写,或追加、或覆盖,如果不存在,系统会直接创建
4、输出流的输出需要调用flush()方法刷新一下将数据写出,而close()方法在关闭系统资源时会自动的刷新一下。
5、close()方法:java本身没有操作文件的功能,但是可以调用操作系统的功能实现文件的读写,而操作完,需要告诉操作系统关闭文件操作功能。close()就是这个作用!
- package com.heronsbill.stremtest;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
-
- /**
- * @Author: heronsbill
- * @DATA: 2019/8/26
- */
- public class Test4 {
- public static void main(String[] args) throws Exception {
- // 加载jpg图片
- File fileRead = new File("D:\\aaa\\IMG_20160721_212853_HDR.jpg");
- // 图片输出路径
- File fileWrite = new File("D:\\aaa\\aaa\\def.jpg");
- // 读图片信息
- FileInputStream fileInputStream = new FileInputStream(fileRead);
- // 写图片信息
- FileOutputStream fileOutputStream = new FileOutputStream(fileWrite, true);
- // 定义字节数组,用来接收FileInputStream读到的字节
- long a = System.currentTimeMillis();
- int len = 0;
- int i = 0;
- // 当读完的时候会返回-1
- while (( len = fileInputStream.read()) != -1) {
- fileOutputStream.write(len);
- System.out.println(i++);
- }
- long b = System.currentTimeMillis();
-
- fileOutputStream.close();
- fileInputStream.close();
- System.out.println(b-a);
-
-
- }
-
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
最后一个4.48M的图片经历61970ms(62s)实现了复制功能,我们可以看到使用字节流一个一个的取读取字节来实现复制功能效率太低,我们可以通过添加定长的字节数组(长度越高,速度越快,但需要根据电脑配置进行设置,一般定义为1024位的长度)来接收输入流读取的信息的方式来提高效率
- byte[] bytes = new byte[1024];
- int i = 0;
- // 当读完的时候会返回-1
- while (fileInputStream.read(bytes) != -1) {
- fileOutputStream.write(bytes);
- System.out.println(i++);
- fileOutputStream.flush();
- }
这样,时间就大大缩短到了122ms,可是在实际应用中这样的速度仍然是慢,那么缓冲流就是用来解决传统字节流,字符流读取速度过慢的一些类
实现高效的读写
四种缓冲流
字节缓冲流:BufferedInputStream(InputStream in),BufferedOutputStream(OutputStream out)
字符缓冲流:BufferedReader(Reader in),BufferedWriter(Writer out)
字符缓冲流的特有方法:
BufferedReader:public String readLine():读一行文字,返回读取的内容,当返回null时,就是读完了
BufferedWriter:public void newline():写行分隔符,行分隔符由系统定义(\n或\r\n等等),也就是换行
在读取配置文件时使用缓冲流 BufferedReader的readLine()方法直接读取一行,是一个相当不错的方法
下面用缓冲流实之前的文件的复制
- package com.heronsbill.stremtest;
-
- import java.io.*;
-
- /**
- * @Author: heronsbill
- * @DATA: 2019/8/26
- */
- public class Test6 {
- public static void main(String[] args) throws Exception {
- // 加载jpg图片
- File fileRead = new File("D:\\aaa\\IMG_20160721_212853_HDR.jpg");
- // 图片输出路径
- File fileWrite = new File("D:\\aaa\\aaa\\niuniu.jpg");
- // 读图片信息
- FileInputStream fileInputStream = new FileInputStream(fileRead);
- // 写图片信息
- FileOutputStream fileOutputStream = new FileOutputStream(fileWrite, true);
- // 创建缓冲流
- BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
- BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
- // 定义接收字节的数组
- byte[] b =new byte[1024];
- long l = System.currentTimeMillis();
- // 遍历打印
- while (bufferedInputStream.read(b)!=-1){
- bufferedOutputStream.write(b);
- }
- long l1 = System.currentTimeMillis();
- // 输出复制所用时间
- System.out.println(l1-l);
- // 关闭资源
- bufferedOutputStream.close();
- bufferedInputStream.close();
- fileOutputStream.close();
- fileInputStream.close();
-
-
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
同样是4.48M的图片复制下来只需要23ms
转换流的实际应用,是将一种编码格式的流转换另一种编码格式,它是字节与字符之间的桥梁(如下图),
InputStreamReader 字节流到字符流的桥梁,是一个解码的过程
InputStreamReader(InputStream in):创建一个使用默认字符集的输入转换流
InputStreamReader(InputStream in , String charsetName)创建一个指定字符集的输入转换流
OutputStreamWriter 字符流到字节流的桥梁,是一个编码的过程
OutputStreamWriter(OutputStream out):创建一个使用默认字符集的输出转换流
OutputStreamWriter(OutputStream out,String charsetName):创建一个指定字符集的输出转换流
Java提供的一种序列化机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据,对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,就相当于在文件中持久保持了一个对象的信息
反之,该字节序列还可以从文件中读取回来,重构对象,对他进行反序列化。对象的数据,对象的类型、对象存储的数据信息,都可以用来在内存中创建对象
序列化
ObjectOutStream类:将java对象的原始数据类型写出到文件,实现对象的持久存储
构造方法:
public ObjectOutputStream(OutputStream out)
属性方法:
writeObject(Object obj) 写对象
反序列化
ObjectInputStream类:将之前使用ObjectOutputStream序列化的原始数据恢复为对象
构造方法:
public ObjectInputStream(InputStream in)
属性方法
readObject():读对象
需要注意的是,一个对象要想实现序列化,反序列化,必须实现序列化接口----Serializable,Serializable是一个标记接口(没有方法的接口),不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException;而且实现序列化的对象类的所有属性必须是可序列化的,即不被static和transient修饰,反之,如果一个属性不需要可序列化,则该属性必须用transient注明是瞬态的
打印流指PrintStream类
平时练习输出语句信息的的时候会用 System.out.println();进行输出,这其实是调用系统默认的输出流,将信息输出在控制台上,而通过PrintStream对象,指定输出路径,再调用System.setOut(ps)方法就可以控制输出打印的位置
创建打印流对象:
PrintStream ps= new PrintStream(“数据目的”)
调用write()方法(因为PrintStream是OutputStream的子类)
ps.write(100)//这个输出的是100在ascii表中对应得字符d
ps.print(乱七八糟一堆)//原生输出
扩:
Syetem.out.println(乱七八糟一堆)的深入理解
PrintStream ps = new PrintStream(Filename filename)
//改变输出的流向
System.setOut(ps);
System.out.println(97)//这个97就不再输出到控制台了,而是输出到filemname中
不同流有不同的功能,但方法都有互通性,可以通过比较的方式进行学习,加深理解。万物皆字节,所有在实际操作中字节流的使用要不字符流多,而使用字节流,也可以有效的避免字节丢失,字节流配合缓存流,又能提高效率。不同系统、文件间的转换势必要考虑编码问题,实际工作中确实会提前将编码格式设置好,但是了解转换流,并熟练使用,对理解程序运行的原理,过程有很大帮助。
能力尚浅,有待进步,如有不足,不吝赐教!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。