一、简介
Java IO主要在java.io包下,分为四大块近80个类:
1、基于字节操作的I/O接口:InputStream和OutputStream
2、基于字符操作的I/O接口:Writer和Reader
3、基于磁盘操作的I/O接口:File
4、基于网络操作的I/O接口:Socket(不在java.io包下)
影响IO性能的无非就是两大因素:数据的格式及存储的方式,前两类主要是数据格式方面的,后两个类是存储方式方面的:本地和网络。所以策划好这两个方面的活动,有助于我们合理使用IO。
IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间的数据传输,Java对于数据的操作都是通过流实现,而java用于操作流的对象都在IO包中。
分类:
Writer 按操作数据分为:字节流和字符流。 如:Reader和InputStream
按流向分:输入流和输出流。如:InputStream和OutputStream
IO流常用的基类:
* InputStream , OutputStream
字符流的抽象基类:
* Reader , Writer
由上面四个类派生的子类名称都是以其父类名作为子类的后缀:
如:FileReader和FileInputStream
二、字符流Reader&Writer
1. 字符流简介:
* 字符流中的对象融合了编码表,也就是系统默认的编码表。我们的系统一般都是GBK编码。
* 字符流只用来处理文本数据,字节流用来处理媒体数据。
* 数据最常见的表现方式是文件,字符流用于操作文件的子类一般是FileReader和FileWriter。
2.字符流读写:
注意事项:
* 写入文件后必须要用flush()刷新。
* 用完流后记得要关闭流
* 使用流对象要抛出IO异常
* 定义文件路径时,可以用“/”或者“\\”。
* 在创建一个文件时,如果目录下有同名文件将被覆盖。
* 在读取文件时,必须保证该文件已存在,否则出异常
示例1:在硬盘上创建一个文件,并写入一些文字数据
示例2:FileReader的reade()方法.
示例3:对已有文件的数据进行续写要求:用单个字符和字符数组进行分别读取
练习:
将F盘的一个文件复制到E盘。
思考:
其实就是将F盘下的文件数据存储到D盘的一个文件中。
步骤:
1.在D盘创建一个文件,存储F盘中文件的数据。
2.定义读取流和F:盘文件关联。
3.通过不断读写完成数据存储。
4.关闭资源。源码:
三、缓冲区
1. 字符流的缓冲区:BufferedReader和BufferedWreiter
* 缓冲区的出现时为了提高流的操作效率而出现的.
* 需要被提高效率的流作为参数传递给缓冲区的构造函数
* 在缓冲区中封装了一个数组,存入数据后一次取出
BufferedReader示例:
读取流缓冲区提供了一个一次读一行的方法readline,方便对文本数据的获取。
readline()只返回回车符前面的字符,不返回回车符。如果是复制的话,必须加入newLine(),写入回车符newLine()是java提供的多平台换行符写入方法。
BufferedWriter示例:
2.装饰设计模式
装饰设计模式::::
要求:自定义一些Reader类,读取不同的数据(装饰和继承的区别)
MyReader //专门用于读取数据的类
|--MyTextReader
|--MyBufferTextReader
|--MyMediaReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader
如果将他们抽取出来,设计一个MyBufferReader,可以根据传入的类型进行增强
class MyBufferReader {
MyBufferReader (MyTextReader text) {}
MyBufferReader (MyMediaReader media) {}
MyBufferReader (MyDataReader data) {}
}
但是上面的类拓展性很差。找到其参数的共同类型,通过多态的形式,可以提高拓展性
class MyBufferReader extends MyReader{
private MyReader r; //从继承变为了组成模式 装饰设计模式
MyBufferReader(MyReader r) {}
}
优化后的体系:
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader //增强上面三个。装饰模式比继承灵活,
避免继承体系的臃肿。降低类与类之间的耦合性
装饰类只能增强已有的对象,具备的功能是相同的。所以装饰类和被装饰类属于同一个体系
MyBuffereReader类: 自己写一个MyBuffereReader类,功能与BuffereReader相同
四、字节流
1.概述:
1、字节流和字符流的基本操作是相同的,但是要想操作媒体流就需要用到字节流。
2、字节流因为操作的是字节,所以可以用来操作媒体文件。(媒体文件也是以字节存储的)
3、读写字节流:InputStream 输入流(读)和OutputStream 输出流(写)
4、字节流操作可以不用刷新流操作。
5、InputStream特有方法:
int available();//返回文件中的字节个数
注:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。练习:
需求:复制一张图片F:\java_Demo\day9_28\1.BMP到F:\java_Demo\day9_28\2.bmp
2. 字节流缓冲区
* 字节流缓冲区跟字符流缓冲区一样,也是为了提高效率。
注意事项:
1. read():会将字节byte()提升为int型值
2. write():会将int类型转换为byte()类型,保留最后的8位。
练习:
1.复制MP3文件 1.MP3 --> 2.MP3
2.自己写一个MyBufferedInputStream缓冲类,提升复制速度
代码:
五、流操作规律
1. 键盘读取,控制台打印。
System.out: 对应的标准输出设备:控制台 //它是PrintStream对象,(PrintStream:打印流。OutputStream的子类)
System.in: 对应的标准输入设备:键盘 //它是InputStream对象
示例:
2. 整行录入
1.从键盘录入数据,并存储到文件中。
2. 我们在键盘录入的是时候,read()方法是一个一个录入的,能不能整行的录入呢?这时候我们想到了BufferedReader中ReadLine()方法。
3. 转换流
为了让字节流可以使用字符流中的方法,我们需要转换流。
1. InputStreamReader:字节流转向字符流;
a、获取键盘录入对象。InputStream in=System.in;
b、将字节流对象转成字符流对象,使用转换流。
InputStreamReaderisr=new InputStreamReader(in);
c、为了提高效率,将字符串进行缓冲区技术高效操作。使用BufferedReader
BufferedReaderbr=new BufferedReader(isr);
//键盘录入最常见写法
BufferedReaderin=new BufferedReader(new InputStreamReader(System.in));
2.OutputStreamWriter:字符流通向字节流
示例:
4. 流操作基本规律
为了控制格式我将其写入了Java代码段中,如下:
示例1:文本 ~ 文本
5.指定编码表(转换流可以指定编码表)
要求:用UTF-8编码存储一个文本文件
原文: http://www.cnblogs.com/xll1025/p/6418766.html