输入流和输出流相对于内存设备而言.
将外设中的数据读取到内存中:输入 将内存的数写入到外设中:输出。
字符流的由来: 其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表。获取对应的文字。 在对这个文字进行操作。简单说:字节流+编码表
---------------------------------------
字节流的两个顶层父类: 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"中。