IO知识梳理1
---------------------------------------------------------------------------------------------------------------------------------------------
1、字符流 Reade--Writer
2、字节流InputStream--OutputStream
2、字节流InputStream--OutputStream
3、4个顶层类都是抽象类。
由这4个类派生出的子类名称都是以其父类名作为子类的后缀。
3、操作纯文本--字符流 非纯文本如图片、视频--字节流
4、BufferedReader bufr = //键盘录入 最常见的写法。 重点
4、BufferedReader bufr = //键盘录入 最常见的写法。 重点
new BufferedReader(new InputStreamReader(System.in));
5、读取文件,并写入一个新的文件。 通过缓冲区进行效率的提高。
写入时,一定要注意 换行--刷新--关闭 资源动作。
6、流操作最痛苦的就是,流对象有很多,不知道用那一个。
通过【三个明确】来完成。1、明确 源和目的。2、明确 操作的数据是否为纯文本。3、当体系明确后,在明确要使用那个具体的对象。
7、装饰设计模式:构建一个新的类,把已有的对象传入进行功能的增强
一旦自己的方法出BUG,还可以使用原来的功能。BufferedReader 等就是装饰类。
8、LineNumberReader 代行号的增强类。
setLineNumber() 写入行号 括号内为起始数字getLIneNumber() 获取行号
9、转换流什么时候用,字符,字节之间的桥梁,通常涉及到字符编码转换时,需要用到转换流
-------------------------------------------------------
【1】
-------------------------------------------------------
【1】
1、3个明确
|-- Reader
源: 读取 |-- InputStream
明确源和目的
目的: 写入 |-- Writer
|-- OutputStream
----------------------------
|--Reader
是 |--Writer
明确是否纯文本
否 |--InputStream
|-- OutputStream
----------------------------
内存 |-- ByteArrayInputStream
硬盘 -|--FieReader
源设备 -|--FileInputStream
键盘 |--System.in
明确设备
内存 |--ByteArrayOutputStream
目的设备 硬盘 -|-- FileWriter
-|-- FileOutputStream
控制台 |-- System.out
----------------------------------------------------------------
2-1、转换流
InputStreamReader---OutputStreamWriter
字节> 字符 字符>字节
2-2、缓冲区
BufferedReader--BufferedWriter
BufferedInputStream-BufferedOutputStream
2-3
LineNumberReader: 跟踪行号的缓冲字符输入流
1、getLineNumber() 获取行号2、setLineNumber(int lineNumber) 设置当前行号。
2-4、 字节流里的 read、write
read 返回的值是int 说明存在类型提示,在数据的高位补0,放置出现-1的情况write 输出的是byte,说明存在强制转型,就不会造成文件变大。
2-5、更改标准输入、输出设备
System.setIn();System.setOut();
IOException--IO异常 捕获的CATCH异常,告诉操作者路径不对
NullPointerException 空指针异常 当流没有被创建而进行了关闭动作。 需要进行null判断
----------------------------------------------------------------
【2】
//COPY
class $3CopyTestByBuf{
public static void main(String[] args) {
//创建出读取、写入流,以及读取、写入缓冲区。
FileReader fr = null;
FileWriter fw = null;
BufferedReader brr =null;
BufferedWriter brw =null;
try{
//指定读取、写入流并关联文件
fr = new FileReader("Test8.java");
fw =new FileWriter("D:\\Test8.java");
//把需要优化的流放入相应的缓冲区,进行高效运作。
brr = new BufferedReader(fr);
brw = new BufferedWriter(fw);
//通过读取整行,并写入的方式进行拷贝,注意【换行】和【刷新】
String str = null;
while((str=brr.readLine())!=null){
//brw.write(str,0,str.length());//把读取的一行插入
brw.write(str);//直接写入就可以了,因为有换行,上面一句复杂了
brw.newLine();//换行动作
brw.flush();//刷新动作
}
}
catch(IOException e){
System.out.println(e.toString());
}
finally{
try{
if(brr!=null)
brr.close(); //【一定要关闭】
}
catch(IOException e){
System.out.println(e.toString());
}
finally{
try{
if(brw!=null)
brw.close();//【一定要关闭】
}
catch(IOException e){
System.out.println(e.toString());
}
}
}
}
}
读取文件,并写入一个新的文件。 通过缓冲区进行效率的提高。
1、写入时,一定要注意换行、刷新。 最后是关闭资源动作。
【3】
装饰模式
装饰设计模式的有优点,继承的区别。
模拟追溯Reader当时的创建
我们设计出一个用于读取数据的类
并设计出具体不同功能的子类
设计出缓冲技术,继承子类并对其进行增强
装饰模式
装饰设计模式的有优点,继承的区别。
模拟追溯Reader当时的创建
我们设计出一个用于读取数据的类
并设计出具体不同功能的子类
设计出缓冲技术,继承子类并对其进行增强
MyReader
|--MyTextReader //Test
|--MyBurredTestReader
|--MyMediaReader //Media
|--MyBurredMediaReader
|--MyDataReader //Date
|--MyBurredDateReader
这样就设计出一个体系,后来我们发现该体系臃肿,
发现缓冲技术是共性的,所以我们提炼出来:
class MyBufferedReader{
MyBufferedReader(MyTextReader test){}
MyBufferedReader(MyMediaReader media){}
}
可是该方法扩展性依旧不够:
找到其参数的共同类型,通过多态的形式,可以提高扩展性,
多态是要继续才有的。而共同类型就是 MyReader
所以:
class MyBufferedReader extends MyReader{
Private MyReader r;
MyBufferedReader(MyReader r){}
}
经过一步步的优化,我们原来设计的体系就发生了一些变化:
MyReader
|--MyTextReader //Test
|--MyMediaReader //Media
|--MyDataReader //Date
|--MyBufferedReader (他里面没有东西,都是基于MyReader下其他类的东西并增强)
相对与原来的体系,更清晰了很多,
------------------------------------------------------------
这就是装饰设计体系模式对原有体系进行优化而产生的体系。
就是将原来臃肿的继承体系优化后变的更简单,更具有扩展性。
装饰模式比继承要灵活,避免了继承体系的臃肿
并降低了类与类之间的关系。(不用在必须继承)
装饰类因为是增强已有对象,具备 的功能和已有对象是相同的,只不过提供了,更强的功能,
所以装饰类和被装饰类,通常都属于一个体系中。
装饰设计模式把继承结构改成了组合结构。
---------------------------------------------------------------------------------
(什么时候用装饰设计模式呢,譬如你接收一个项目,有些功能是以前写的,你不可能改动呀,
那么写一个增强类,把原来的功能传递进来并增强,一旦自己的方法出BUG,还可以使用原来的功能。)
。。。。。。。。。。。。。。。。。。。。
装饰设计模式
当想要把已有的对象进行功能的增强时,
可以定义类,将已有对象传入,基于已有的功能,并提供加强功能
那么自定义的类称为装饰类。
装饰类,通常会通过构造方法接收被装饰的对象
并基于该被装饰的对象功能,提供更强的功能。
BufferedReader 等就是装饰类。
要增强类 和增强类, 都应该同属于一个类或者一个接口。是一个体系中的成员。
class Person{
public void chifan(){
System.out.println("吃饭");
}
}
class SuperPerson {
private Person p ;
SuperPerson(Person p){//增强功能必须要先有原有功能。
this.p = p;
}
public void superchifan(){//功能的增强。
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
}
}
class ZhuangshiMoshi5{
public static void main(String[] args) {
Person p = new Person ();
//p.chifan();
//把要增强的功能放入增强类中。
SuperPerson sp = new SuperPerson(p);
sp.superchifan();
}
}
代行号的增强类。
LineNumberReader 提供了
setLineNumber() 写入行号 括号内为起始数字
getLIneNumber() 获取行号
FileReader fr = new FileReader("Test8.java");
LineNumberReaderlnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(50);//【3】设置行号 会从51开始进行行号累计。
while((line=lnr.readLine())!=null){
//System.out.println(line);//【1】 成功读取
System.out.println(lnr.getLineNumber()+"|"+line);//【2】加入行号
}
【5】
复制一张图片。
思路
1、用字节流读取对象和图片关联
2、用字节流写入流对象创建一个图片文件,用于储存取到的图片数据。
3、通过循环读写,完成数据的存储。
4、关闭资源
class CopyPicTest9 {
public static void main(String[] args) {
copy();
}
public static void copy(){
FileOutputStream fos =null;
FileInputStream fis =null;
try{
fos = new FileOutputStream("D:\\p.jpg");//写
fis = new FileInputStream("E:\\p.jpg");//读
byte [] by = new byte[1024];
int len = 0;
while((len=fis.read(by))!=-1){
fos.write(by,0,len);
}
}
catch(IOException e){
System.out.println(e.toString());
}
finally{
try{
if(fis!=null)
fis.close();
}
catch(IOException e){
System.out.println(e.toString());
}
finally{
try{
if(fos!=null)
fos.close();
}
catch(IOException e){
System.out.println(e.toString());
}
}
}
}
}
图片,视频等非文本文件,需要使用字节流来操作。需要注意的是,字节流,
byte [] by = new byte[1024];
int len = 0;
while((len=fis.read(by))!=-1){
fos.write(by,0,len);
}
而字符流是:
//char [] ch = new char[1024];
String str = null;
while((str=brr.readLine())!=null){
//brw.write(str,0,str.length());//把读取的一行插入
brw.write(str);//直接写入就可以了,因为有换行,上面一句复杂了
brw.newLine();//换行动作
brw.flush();//刷新动作
}
接收键盘录入:
InputStream in = System.in;
【6】
转换流
通过刚才的【ReadIn92】键盘录入一行的数据并打印其大写,发现,其实就是读一行数据的原理。
也就是readLine() 方法。 能不能直接使用readLine 方法来完成键盘录入的一行数据进行读取呢?
readLine 方法是【字符流】 BufferedReader 类中的方法
而键盘录入的read 方法是【字节流】InputStream 类中的方法
那么能不能把【字节流】转换为【字符流】,然后使用字符流的缓冲区的readLine方法呢?
这就是转换流。
既然有字节流转向字符流肯定就有字符流转向字节流。
我们输入的时候是字符,而存入硬盘的都是字节数据。
InputStreamReader
OutputStreamWriter
转换流
通过刚才的【ReadIn92】键盘录入一行的数据并打印其大写,发现,其实就是读一行数据的原理。
也就是readLine() 方法。 能不能直接使用readLine 方法来完成键盘录入的一行数据进行读取呢?
readLine 方法是【字符流】 BufferedReader 类中的方法
而键盘录入的read 方法是【字节流】InputStream 类中的方法
那么能不能把【字节流】转换为【字符流】,然后使用字符流的缓冲区的readLine方法呢?
这就是转换流。
既然有字节流转向字符流肯定就有字符流转向字节流。
我们输入的时候是字符,而存入硬盘的都是字节数据。
InputStreamReader
OutputStreamWriter
class InputStreamReader93
{
public static void main(String[] args) throws IOException
{
//1、创建字节流接收一个键盘录入
//1-2、把字节流放入转换流,转换为字符流
//1-3、把字符流进行缓冲技术提高效率
//2-1、创建一个写入字节流,2-2并转换为写入字符流,2-3并放入缓冲区。
//InputStream in = System.in;//【1】-1
//InputStreamReader isr = new InputStreamReader(in);//【1】-2 转换流。
//BufferedReader bufr = new BufferedReader(isr);//【1】-3
//OutputStream os = System.out;//【2】-1
//OutputStreamWriter osw = new OutputStreamWriter(os);//【2】-2 转换流
//BufferedWriter bufw = new BufferedWriter(osw);//【2】-3
//【把1,2,进行简写】
BufferedReader bufr =//键盘录入 最常见的写法。 重点
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=
new BufferedWriter(new OutputStreamWriter(System.out));
//【4】:
String line = null;
while((line = bufr.readLine())!=null){ // BufferedReader 缓冲区方法。
if("over".equals(line))//设置一个结束标记
break;
//System.out.println(line.toUpperCase());
bufw.write(line.toUpperCase());
>bufw.newLine();//缓冲区方法。换行
bufw.flush();//刷新 写入数据一定不要忘记两大步奏---刷新-关闭。。
}
bufr.close();
bufw.close();
}
}
InputStreamReader---OutputStreamWriter 把流进行转换
【7】
【流操作的基本规律】:
最痛苦的就是,流对象有很多,不知道用那一个。
通过【三个明确】来完成。
1、明确 源和目的。
源 : 输入流 InputStream Reader目的: 输出流 OutputStream Writer
2、明确 操作的数据是否为纯文本。
是: 字符流否: 字节流
3、当体系明确后,在明确要使用那个具体的对象。
通过设备来区分:源设备 : 内存、硬盘、键盘。目的设备: 内存、硬盘、控制台。
-------
根据以上3点,写出3个需求。
1、将一个文本文件中的数据存储到另一个文件中。复制文件。
根据以上3点,写出3个需求。
1、将一个文本文件中的数据存储到另一个文件中。复制文件。
分析:
1、源: 因为是源,所以使用读取流:InputStream Reader是不是操作文本文件是!这时候就选择:Reader这时候体系就明确了。接下来明确要是用体系中的那个对象。明确设备:硬盘 。上的一个文件。Reader 体系中,可以操作文件的对象是: FileReader是否需要提高效率: 是! 加入Reader体系中的缓冲区。
FileReader fr = new FileReader("a.txt");BufferedReader bufr = new BufferedReader(fr);
2、目的: OutputStream Writer是否为纯文本是!Writer设备:硬盘,一个文件Writer 体系中,可以操作文件的对象是: FileWriter
是否需要提高效率: 是! 加入Writer体系中的缓冲区。
FileWriter fw = new FileWriter("a.txt");BufferedWriter bufw =new BufferedWriter(fw);
-----------------------------
练习: 将一个图片文件中数据存储到另一个文件中,复制文件,要求同上,自己分析出3个明确。
分析:
1 源 : 源都是读取流,InputStream Reader
练习: 将一个图片文件中数据存储到另一个文件中,复制文件,要求同上,自己分析出3个明确。
分析:
1 源 : 源都是读取流,InputStream Reader
而图片文件不是纯文本文件所以用InputStream而目设备是电脑中一文件。而在InputStream中操作文件的对象是 FileInputStream所以: 然后考虑是否需要缓冲技术:FileInputStream in = new FileInputStream()
2 目的: OutputStream Writer
操作的不是纯文本文件 OutputStream而目设备是电脑中一文件。而在OutputStream中操作文件的对象是 FileOutputStream所以: 然后考虑是否需要缓冲技术:FileOutputStream out = new FileOutputStream();
---------------------------------------------------------------
2、需求,将键盘录入的数据存到一个文件当中
分析:1、源:InputStream Reader
2、需求,将键盘录入的数据存到一个文件当中
分析:1、源:InputStream Reader
是不是纯文本? 是! 选择 Reader设备是 键盘 对应的对象是: System.in问题来了,Reader是字符流,System.in是字节流对象为了操作键盘的文本数据方便,转为字符流按照字符串操作是最方便的所以明确了 Reader 那么将System.in 转换成Reader用到Reader 中的转换流,InputStreamReaderInputStreamReader isr = new InputStreamReader(System.in);是否需要缓冲技术进行效率的提高?BufferedReader bufr =new BufferedReader(new InputStreamReader(System.in));
2、目的地: OutputStream Writer是不是纯文本? 是 ! Writer设备是:硬盘 一个文件 所以操作对象是: FileWriterFileWriter fw = new FileWriter();需要缓冲技术吗,BufferedWriter bufw = new BufferedWriter()
------------
【7-2】【重点】扩展:想要把录入的数据按照指定编码表,将数据存储到文件中
2、目的地: OutputStream Writer
【7-2】【重点】扩展:想要把录入的数据按照指定编码表,将数据存储到文件中
2、目的地: OutputStream Writer
是不是纯文本? 是 ! Writer设备是:硬盘 一个文件 所以操作对象是: FileWriter但是FileWriter 使用的是默认编码表:GBK【但是存储时,需要加入指定编码表 utf-8 而指定的编码变 只有转换流可以指定所以要使用的对象是 OutputStreamWriter.而该转换流对象要接收一个字节输出流,而且还可以操作的文件的字节输出流:FileOutputSteam】OutputStreamWriter osw = new OutputStreamWriter(new FileOutputSteam("a.txt"),"UTF_8");【指定编码表】需要高效吗?BuffreedWriter bufw =new BuffreedWriter(osw);>>>>>写成一句话:BuffreedWriter bufw =new BuffreedWriter(new OutputStreamWriter(new FileOutputSteam("a.txt"),"UTF_8"));
记住:
转换流什么时候用,字符,字节之间的桥梁,通常涉及到字符编码转换时, 需要用到转换流
练习:将一个文本数据打印到控制台上,按照上列要求,写出3个明确。
分析 1 、 源,InputStream Reader
分析 1 、 源,InputStream Reader
是不是纯文本? 是 所以 Reader设备:硬盘,一个文件 所以FileReader是否需要高效BufferedReader bufr = new BufferedReader(new FIleReader("a.txt"));2、目的, OutputStream Writer是不是纯文本? 是! Writer设备: 控制台 对应的对象是:System.outWriter 字符流,而System.out 是字节流。 那么需要进行转换OutputStreamWriter osw = new OutputStreamWriter(System.out);是否需要提高效率BufferedWriter bufw = new BufferedWriter(osw);
------------------------------------------------------
class TransStreamDemo94{
public static void main(String[] args) throws IOException{
//show_1();
show_2();
}
public static void show_1() throws IOException{
// 了解下(不常用。): System.setIn 和System.setOut
// System.setIn(new FileInputStream("Test8.java"));
// System.setOut(new PrintStream("zzz.txt"));
//【】括号内对应最定上需求。
BufferedReader bufr = //键盘录入
new BufferedReader(new InputStreamReader(System.in));//【1】【2】
//new BufferedReader(new InputStreamReader(new FileInputStream("E:\\123.txt")));//【3】
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\12345.txt"),"UTF-8"));//【2】
//new BufferedWriter(new OutputStreamWriter(System.out));//【1】【3】
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
}
//练习:将一个文本数据打印到控制台上,按照上列要求,写出3个明确。分析在上。
public static void show_2() throws IOException{
BufferedReader bufr = new BufferedReader(new FileReader("Test.txt"));
BufferedWriter bufw =
new BufferedWriter(new OutputStreamWriter(System.out));
String str = null;
while((str=bufr.readLine())!=null){
bufw.write(str);
bufw.newLine();
bufw.flush();
}
bufr.close();
bufw.close();
}
}
通过键盘写入3个文件,一个是不指定编码变,一个指定GBK 一个指定UTF-8
后比较3个文件发现,同样输入“你好” 的情况下三个文件,前2者都是6个字节,后者8个字节
字符编码后面在具体温习。
---------------------------------------------------------------------------------------------------------------------------------------------
----------
android培训、
java培训、期待与您交流!----------
----------------------------------------------