关于IO流操作

输入流和输出流相对于内存设备而言.

将外设中的数据读取到内存中:输入
将内存的数写入到外设中:输出。


字符流的由来:
其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。
在对这个文字进行操作。简单说:字节流+编码表 

---------------------------------------

字节流的两个顶层父类:
1,InputStream  2,OutputStream.

字符流的两个顶层父类:
1,Reader 2,Writer

这些体系的子类都以父类名作为后缀。 
而且子类名的前缀就是该对象的功能。

就从熟悉的文字开始字符流,


//需求:将一些文字存储到硬盘一个文件中。
记住;如果要操作文字数据,建议优先考虑字符流。
而且要将数据从内存写到硬盘上,要使用字符流中的输出流。Writer
硬盘的数据基本体现是文件。 希望找到一个可以操作文件的Writer.

找到了FileWriter

//需求:读取一个文本文件。将读取到的字符打印到控制台.
同上,找到了FileReader

作业:将c盘的一个文本文件复制到d盘。
分析:
复制原理:
读取c盘文件中的数据,
将这些数据写入到d盘当中。
连读带写。

==========================

字符流缓冲区:
BufferedWriter 
    :newLine();
    
BufferedReader:
    : readLine();


使用缓冲区复制一个文本文件。 

装饰设计模式:
    对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。 
    

装饰和继承都能实现一样的特点:进行功能的扩展增强。 

有什么区别呢?

首先有一个继承体系。
Writer
    |--TextWriter:用于操作文本
    |--MediaWriter:用于操作媒体。
    
想要对操作的动作进行效率的提高。
按照面向对象,可以通过继承对具体的进行功能的扩展。 
效率提高需要加入缓冲技术。
    
Writer
    |--TextWriter:用于操作文本
        |--BufferTextWriter:加入了缓冲技术的操作文本的对象。
    |--MediaWriter:用于操作媒体。
        |--BufferMediaWriter:

到这里就哦了。但是这样做好像并不理想。
如果这个体系进行功能扩展,有多了流对象。
那么这个流要提高效率,是不是也要产生子类呢?是。这时就会发现只为提高功能,进行的继承,
导致继承体系越来越臃肿。不够灵活。 

重新思考这个问题?
既然加入的都是同一种技术--缓冲。
前一种是让缓冲和具体的对象相结合。 
可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。

class Buffer{
    Buffer(TextWriter w)
    {}
    
    Buffer(MediaWirter w)
    {
    
    }
}
class BufferWriter extends Writer{
    BufferWriter(Writer w)
    {
    }
}
Writer
    |--TextWriter:用于操作文本
    |--MediaWriter:用于操作媒体。
    |--BufferWriter:用于提高效率。
    
装饰比继承灵活。

特点:装饰类和被装饰类都必须所属同一个接口或者父类。 

--------------------------------------

字节流:

InputStream  
    

OutputStream

字节流:
FileInputStream 
FileOutputStream
BufferedInputStream
BufferedOutputStream
字符流:
Writer Reader
FileReader
FileWriter
BufferedReader
BufferedWriter


================================================================

转换流:
InputStreamReader :字节到字符的桥梁。解码。
OutputStreamWriter:字符到字节的桥梁。编码。

流的操作规律:
之所以要弄清楚这个规律,是因为流对象太多,开发时不知道用哪个对象合适。

想要知道开发时用到哪些对象。只要通过四个明确即可。

1,明确源和目的(汇)
    源:InputStream  Reader
    目的:OutputStream  Writer

2,明确数据是否是纯文本数据。
    源:是纯文本:Reader
        否:InputStream
    目的:是纯文本 Writer
        否:OutputStream
    
    到这里,就可以明确需求中具体要使用哪个体系。
    
3,明确具体的设备。
    源设备:
        硬盘:File
        键盘:System.in
        内存:数组
        网络:Socket流
        
    目的设备:
        硬盘:File
        控制台:System.out
        内存:数组
        网络:Socket流

4,是否需要其他额外功能。
    1,是否需要高效(缓冲区);
        是,就加上buffer.
    2,转换。
    


需求1:复制一个文本文件。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本?
        是!
        源:Reader
        目的:Writer
        
    3,明确具体设备。
        源:
            硬盘:File
        目的:
            硬盘:File
    
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("b.txt");
        
    4,需要额外功能吗?
        需要,需要高效。
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
================================================

需求2:读取键盘录入信息,并写入到一个文件中。
        
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确设备
        源:
            键盘。System.in
        目的:
            硬盘。File
            
        InputStream in = System.in;
        FileWriter fw = new FileWriter("b.txt");
        这样做可以完成,但是麻烦。将读取的字节数据转成字符串。再由字符流操作。
    4,需要额外功能吗?
        需要。转换。    将字节流转成字符流。因为名确的源是Reader,这样操作文本数据做便捷。
            所以要将已有的字节流转成字符流。使用字节-->字符 。InputStreamReader
        InputStreamReader isr = new InputStreamReader(System.in);
        FileWriter fw = new FileWriter("b.txt");
        
        还需要功能吗?
        需要:想高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new FileWriter("b.txt"));
        
            
        
===================================================
    
需求3:将一个文本文件数据显示在控制台上。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确具体设备
        源:
            硬盘:File
        目的:
            控制台:System.out
            
        FileReader fr = new FileReader("a.txt");
        OutputStream out = System.out;//PrintStream
    4,需要额外功能吗?
        需要,转换。
        FileReader fr= new FileReader("a.txt");
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        需要,高效。 
        BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
================================================================

需求4:读取键盘录入数据,显示在控制台上。
    1,明确源和目的。
        源:InputStream Reader
        目的:OutputStream  Writer
    2,是否是纯文本呢?
        是,
        源:Reader
        目的:Writer
    3,明确设备。
        源:
            键盘:System.in
        目的:
            控制台:System.out
        
        InputStream in = System.in;
        OutputStream out = System.out;
        
    4,明确额外功能?
        需要转换,因为都是字节流,但是操作的却是文本数据。
        所以使用字符流操作起来更为便捷。
        InputStreamReader isr = new InputStreamReader(System.in);
        OutputStreamWriter osw = new OutputStreamWriter(System.out);
        
        为了将其高效。
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
        
        
============================================================

5,将一个中文字符串数据按照指定的编码表写入到一个文本文件中.
    
    1,目的。OutputStream,Writer
    2,是纯文本,Writer。
    3,设备:硬盘File 
    FileWriter fw = new FileWriter("a.txt");
    fw.write("你好"); 
    
    注意:既然需求中已经明确了指定编码表的动作。
    那就不可以使用FileWriter,因为FileWriter内部是使用默认的本地码表。
    只能使用其父类。OutputStreamWriter.
    OutputStreamWriter接收一个字节输出流对象,既然是操作文件,那么该对象应该是FileOutputStream
    
    OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName);
    
    需要高效吗?
    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),charsetName));

什么时候使用转换流呢?

    1,源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁。
        提高对文本操作的便捷。
    2,一旦操作文本涉及到具体的指定编码表时,必须使用转换流 。
    


 

 

day22 学习结果:

1,流的操作规律。四个明确必须记住,并应用?

2,将提到的5个需求必须全用 需求,规律(思路),代码,来体现?必须做!!!

3,File对象基本使用。了解创建,删除,获取,判断等。

4,File对象的过滤器。

5,递归的使用和注意事项,并举例。

6,列出一个目录中所有的内容,包含子目录。以及删除一个带内容的目录,任选其一。

7,Properties的所有方法的使用,以及应用场景和其练习都要会!

键值对配置信息。properties就可以解析。

id=003
name=lisi
age=30

xml配置信息。可以使用Java中提供的对象,也可以使用第三方工具。DOM4j 
<persons>
    <person id="003">
        <name>lisi</name>
        <age>30</age>    
    </person>
    
    <person id="007">
        <name>lisi3</name>
        <age>33</age>    
    </person>
</persons>

8,综合练习必须先明确思路,然后注意代码细节。找时间完整搞定。

综合练习题:

1,
取出D:盘下全部的.java文件的文件路径保存在java.txt文件中


2,
有五个学生,每个学生有3门课的成绩,定义一种比较直观的文本文件格式,
输入学生姓名和成绩,输入的格式:name,30,30,30从键盘输入以上数据(包括姓名,三门课成绩),
按总分数从高到低的顺序将学生信息存放在磁盘文件"stu.txt"中。

猜你喜欢

转载自blog.csdn.net/nsjlive/article/details/83381890