I/O
1.流的概念
什么是流?:内存与存储设备之间传输数据的通道。
2.流的分类
流向分类:
- 输入流:将《存储设备(硬盘)》中的内容读入到《内存》中:input
- 输出流:将《内存》中的内容写入到《存储设备(硬盘)》中output
- 文件读入到内存,内存写入到文件
单位分类
-
字节流:以字节为单位,可以读写所有数据
-
字符流:以字符为单位,只能读写本文数据
功能分类
- 节点流:具有实际传输的读写功能(底层)
- 过滤流:在节点流的基础上增强功能
3.字节流使用
字节流的父类(抽象类)详情查看《JDK API》
- InputStream:字节输入流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KYS9xRDr-1620898313524)(F:\日常文件\JavaDocment\图片\image-20210513114008354.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WAERhzm7-1620898313527)(F:\日常文件\JavaDocment\图片\image-20210513114058792.png)]
- OutputStream:字节输出流
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BiSWBV3z-1620898313530)(F:\日常文件\JavaDocment\图片\image-20210513114221975.png)]
字节流子类
-
FileInputStream:一次可读取多个字节(详情可参考JDK API :java/io——inputStream——FileInputStream)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGxJ0kHz-1620898313532)(F:\日常文件\JavaDocment\图片\image-20210513115225843.png)]
-
FileOutputStream:一次可写入多个字节(详情可参考JDK API :java/io——outputStream——outFileInputStream)
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V1E27Okw-1620898313533)(F:\日常文件\JavaDocment\图片\image-20210513115359313.png)]
测试代码
InputStream:
public static void main(String[] args) throws Exception{
System.out.println("inputStream");
/*Io流
演示FileInputStream
文件字节输入流
创建FileInputStream,并实例化指定文件路径。抛出异常Throw Exception*/
FileInputStream fis= new FileInputStream("F:\\inputStream.txt");
/*//1.单个字节读取文件
fis.read();
int data = 0;
//当读取字节为-1则结束读取,不为-1则一个接一个读取(注意:字节大于-1)
while ((data=fis.read())!=-1){
//data为ascii码,需要强转
System.out.println("获取到字节:"+(char)data);
}*/
//2.多个字节读取文件
/*byte[] buf = new byte[3];//一般情况下大雨1024
int count= 0;
while ((count=fis.read(buf))!=-1){
System.out.println(new String(buf,0,count));
}*/
//读取完毕:关闭
fis.close();
System.out.println("执行完毕");
}
outputStream:输出流
public static void main(String[] args)throws Exception {
//创建一个文件输出流对象,并实例化new FileOutputStream();
FileOutputStream fos = new FileOutputStream("F:\\outputStream.txt");
/*fos.write(97);
fos.write('b');
fos.write('n');
输出结果是在F:\\outputStream.txt 有abn
以上是简单单个字节写入
*/
// String string ="abcdefghigkl";
String string ="我是谁";
fos.write(string.getBytes());
//关闭
fos.close();
}
使用字节流复制文件
思路:见文件读取出来再写入,所以同时使用了inputStream 和outputStream。
代码实现:
public static void main(String[] args)throws Exception {
//首先创建一个输入流对象
FileInputStream fis =null;
//再创建一个输出流对象
FileOutputStream fos = null;
//实例化对象,并指定路径
fis=new FileInputStream("F:\\inputStream.txt");
fos=new FileOutputStream("F:\\outputStream.txt");
//读取文件内内容,使用多字节流读取
//首先创建一个数组
byte[] bytes = new byte[1024];
int count=0;
//读取
while ((count=fis.read(bytes))!=-1){
//将读取的值,写入到文件
fos.write(bytes,0,count);
}
//关闭
fis.close();
fos.close();
System.out.println("复制成功");
}
优化字节流:字节缓冲流BufferedInputStream/BufferedOutputStream
作用:1.这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,提高了IO的性能。
2.将数据先存储到缓冲区,再通过flush将缓存区的内容写入到文件,途中可关闭。
- bufferedInputStream输入缓冲
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drpSr6Yg-1620898313535)(F:\日常文件\JavaDocment\图片\image-20210513153429137.png)]
- BufferedOutputStream输出缓冲 需要使用flush()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7lEKLQdb-1620898313536)(F:\日常文件\JavaDocment\图片\image-20210513153502558.png)]
- 代码实现:
public static void main(String[] args) throws Exception{
//创建一个输入字节流文件
FileInputStream fis = new FileInputStream("F:\\inputStream.txt");
//创建一个输出字节流文件
FileOutputStream fos = new FileOutputStream("F:\\outputStream1.txt");
//将字节流放入缓冲区bufferedInputStream中:大小为8K
BufferedInputStream bfis= new BufferedInputStream(fis);
//将字节流放入缓冲区BufferedOutputStream中:大小为8K
BufferedOutputStream bois = new BufferedOutputStream(fos);
int count = 0;
//可以使用buffered自带缓存大小8012
//while ((count=bfis.read())!=-1){
//也可以自定义
byte[] byt = new byte[1024];
while ((count=bfis.read(byt))!=-1){
bois.write(count);
//刷新
bois.flush();
}
bfis.close();
bois.close();
}
对象流:(对象调用接口implements Serializable)
1.ObjectInputStream反序列化先前使用ObjectOutputStream编写的原始数据和对象
2.ObjectOutputStream 序列化
3.ObjectOutputStream和ObjectInputStream可以分别为与FileOutputStream和FileInputStream一起使用的对象图提供持久性存储的应用程序。 ObjectInputStream用于恢复先前序列化的对象。 其他用途包括使用套接字流在主机之间传递对象,或者在远程通信系统中进行封送和解组参数和参数。
ObjectInputStream确保从流中创建的图中的所有对象的类型与Java虚拟机中存在的类匹配。 根据需要使用标准机制加载类。
4.ObjectOutputStream将Java对象的原始数据类型和图形写入OutputStream。 可以使用ObjectInputStream读取(重构)对象。 可以通过使用流的文件来实现对象的持久存储。 如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。
只有支持java.io.Serializable接口的对象才能写入流中。 每个可序列化对象的类被编码,包括类的类名和签名,对象的字段和数组的值以及从初始对象引用的任何其他对象的关闭。
总结:对象流就是序列化(ObjectOutputStream)和反序列化(ObjectInputStream)的操作