黑马程序员_Java基础——IO框架(上)(第5篇)
2014-08-08 00:51
519 查看
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、概述
在我看来,IO框架相比于集合框架要复杂得多,许多人肯定不这样认为,但是本人在学习的过程中确实被整得晕头转向,也许到现在还没转过弯儿来呢!那么什么是IO流呢?简单来说就是用于处理设备之间数据传输的东西。在Java中操作数据就是通过流的方式。在硬盘上,文件是数据最常见的表现形式,因而对文件的操作也是IO流最常见的用途。按照流向来分的话,流可分为输出流和输入流。按照操作的数据来分的话又可以分为字符流和字节流。
IO流有4个基本的抽象类,分别是字符流抽象基类Reader、Writer,字节流抽象基类InputStream、OutputStream。这4个基类下又分别拥有自己的装饰类,即使增强类,BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,都是以各自基类的名称为结尾,一一对应的。对于字节流和字符流的转换,Java中也专门提供了解决方案,就是Reader和Writer下的InputStreamReader、OutputStreamWriter两个转换流。其他的一些流也就不再赘述,下面图例一一明了。
二、Writer、Reader
1.FileWriter
Java文档中对FileWriter的描述为用来写入文件字符的便捷类。确实对一开始接触IO流的初学者来说,这个类无疑是具有指导意义的。初始化一个FileWriter对象就会在硬盘上创建一个文件,会根据参数的设定确定是否覆盖原文件。关于这个类更多的也没什么可以多说的,举个例子就一目了然了。
//在硬盘上创建一个文本文件并向里面写入一些东西。
2.FileReader
FileReader用于对文件字符读取的便捷类。这个类可以很放方便的对文件的字符进行读取。初始化一个FileReader对象,其参数中的表示要读取文件,必须存在,否则会抛出文件找不到异常。还是举个例子来讲,更清晰些,也更能便于理解。
//读取一个文本文件E:\\Code\\TreeSetTest.java
从这里我们可以知道,流其实很简单,无非就是读和写,读和写一起组合使用便能够实现简单的文本文件的拷贝。具体示例如下。
//拷贝文本文件
何为装饰设计模式呢?简单来说,当想要对已有的对象进行功能增强时,可以定义类,将已有的对象传入,基于已有的功能,并提供增强功能,那么自定义的该类就被称为装饰类。装饰类通常会通过构造方法接受被装饰的类对象,并基于被装饰的类的功能,提供更强的增强功能。
那么有同学可能会对装饰类和继承会有疑问。为什么要使用装饰类?继承也是可以实现的啊?简单来说,装饰模式比继承更加的灵活,如果一个体系中的所有的类都要增强,那么你会发现,继承的体系将会相当的臃肿,而且代码的重复率相当的高。那么在这个体系中定义装饰类,便会降低类与类之间的关系,避免了大量的继承而使得整个体系的臃肿不堪。
//装饰类的基本示例
BufferedReader为Reader的装饰类,是一个增强类。其具体用法与Reader中的其他流大同小异,只是其提供了更强的、效率更高的功能。比如其重写了int read();和int read(char[], int, int);方法,并增强提供了读取行的方法String readLine();方法。
//自己实现一个Reader的增强类MyBufferedReader
字节流的操作和字符流大同小异,只不过字符流操作的文本,字节流可以操作图片、mp3等媒体文件,其使用的范围更加的广泛。下面通过一个拷贝mp3的例子来说明下。
//拷贝mp3
转换流可以将字节转换成字符,原因在于,其将获得到的字节通过查编码表获取到指定对应字符,其就是基于 字节流 + 编码表,没有转换就没有字符流,所以凡是操作设备上的文本数据,涉及编码转换都必须使用转换流。
转换流的一个最特殊的运用就是标准输入和标准输出。
标准输入(键盘录入):BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
标准输出(屏幕):BufferedWrite bufw = new BufferedWriter(new OutputStreamWriter(System.out));
四、总结-流操作规律
通过以上的学习,我们不难发现,流就是读和写的操作,明确源和目的之后,就很好操作了。
--明确源和目的地
数据源:就是从哪里读取数据,可以使用的两个体系:InputStream、Reader
目的地:就是要往哪里写入数据,可以使用的两个体系为:OutputStream、Writer
--操作的数据是否纯文本
如果是:读-Reader,写-Writer
若不是:读-InputStream,写-OutputStream
--虽然明确了体系,但是体系中有太多的对象,到底用哪个?
数据源对应的设备:硬盘(File)、内存(数组)、键盘(System.in)
目的地对应的设备:硬盘(File)、内存(数组)、控制台(System.out)
--需要在基本操作上附加其他功能吗?比如缓冲
如果需要就进行装饰
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、概述
在我看来,IO框架相比于集合框架要复杂得多,许多人肯定不这样认为,但是本人在学习的过程中确实被整得晕头转向,也许到现在还没转过弯儿来呢!那么什么是IO流呢?简单来说就是用于处理设备之间数据传输的东西。在Java中操作数据就是通过流的方式。在硬盘上,文件是数据最常见的表现形式,因而对文件的操作也是IO流最常见的用途。按照流向来分的话,流可分为输出流和输入流。按照操作的数据来分的话又可以分为字符流和字节流。
IO流有4个基本的抽象类,分别是字符流抽象基类Reader、Writer,字节流抽象基类InputStream、OutputStream。这4个基类下又分别拥有自己的装饰类,即使增强类,BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,都是以各自基类的名称为结尾,一一对应的。对于字节流和字符流的转换,Java中也专门提供了解决方案,就是Reader和Writer下的InputStreamReader、OutputStreamWriter两个转换流。其他的一些流也就不再赘述,下面图例一一明了。
二、Writer、Reader
1.FileWriter
Java文档中对FileWriter的描述为用来写入文件字符的便捷类。确实对一开始接触IO流的初学者来说,这个类无疑是具有指导意义的。初始化一个FileWriter对象就会在硬盘上创建一个文件,会根据参数的设定确定是否覆盖原文件。关于这个类更多的也没什么可以多说的,举个例子就一目了然了。
//在硬盘上创建一个文本文件并向里面写入一些东西。
import java.io.*; class FileWriterDemo { public static void main(String[] args) { FileWriter fw = null; try { //fw = new FileWriter("D:\\demo.txt");//这种方式创建的文件会覆盖已有的文件 fw = new FileWriter("D:\\demo.txt", true);//这种初始化方式会判断,如果已有文件,则续写,没有,则创建,不会覆盖原有文件 fw.write("asdhashdasdasjkdasdaskkjhsd"); fw.flush(); } catch (IOException e) { System.out.println(e.toString()); } finally { try { if(fw != null) fw.close(); } catch (IOException e) { System.out.println(e.toString()); } } } }这段代码看上去挺复杂,其实大部分都是在对异常的处理,核心代码就是try中的三句,相当的简单。
2.FileReader
FileReader用于对文件字符读取的便捷类。这个类可以很放方便的对文件的字符进行读取。初始化一个FileReader对象,其参数中的表示要读取文件,必须存在,否则会抛出文件找不到异常。还是举个例子来讲,更清晰些,也更能便于理解。
//读取一个文本文件E:\\Code\\TreeSetTest.java
import java.io.*; class FileReaderDemo { public static void main(String[] args)throws IOException { FileReader fr = new FileReader("E:\\Code\\TreeSetTest.java");//一定得保证文件存在,否则会报文件找不到异常 /*//第一种方式,一个一个的读,读一个打一个 int ch; while((ch = fr.read()) != -1) { System.out.print((char)ch); } */ //第二种读取方式,读一组存入数组中,然后打印出来 char[] buf = new char[1024]; int len; while((len = fr.read(buf)) != -1) { System.out.print(new String(buf, 0, len)); } fr.close(); } }为了更清晰直观的理解流的学习,我把异常处理的部分直接抛出去了。其中注释中是一个字符一个字符的读取,读一次打印一次,这是最原始的方式。
从这里我们可以知道,流其实很简单,无非就是读和写,读和写一起组合使用便能够实现简单的文本文件的拷贝。具体示例如下。
//拷贝文本文件
import java.io.*; class CopyWenBenWenJian { public static void main(String[] args)throws IOException { FileWriter fw = new FileWriter("D:\\Copy_TreeSetTest.java"); FileReader fr = new FileReader("E:\\Code\\TreeSetTest.java"); char[] buf = new char[1024]; int len; while((len = fr.read(buf)) != -1)//读进数组中 { fw.write(buf, 0, len);//从数组写入文件中 fw.flush(); } fr.close(); fw.close(); } }三、装饰设计模式
何为装饰设计模式呢?简单来说,当想要对已有的对象进行功能增强时,可以定义类,将已有的对象传入,基于已有的功能,并提供增强功能,那么自定义的该类就被称为装饰类。装饰类通常会通过构造方法接受被装饰的类对象,并基于被装饰的类的功能,提供更强的增强功能。
那么有同学可能会对装饰类和继承会有疑问。为什么要使用装饰类?继承也是可以实现的啊?简单来说,装饰模式比继承更加的灵活,如果一个体系中的所有的类都要增强,那么你会发现,继承的体系将会相当的臃肿,而且代码的重复率相当的高。那么在这个体系中定义装饰类,便会降低类与类之间的关系,避免了大量的继承而使得整个体系的臃肿不堪。
//装饰类的基本示例
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("甜点"); System.out.println("来一根"); } } class ZhuangShiDemo { public static void main(String[] args) { Person p = new Person(); p.chiFan(); System.out.println(); SuperPerson sp = new SuperPerson(p); sp.superChiFan(); } }3.BufferedReader
BufferedReader为Reader的装饰类,是一个增强类。其具体用法与Reader中的其他流大同小异,只是其提供了更强的、效率更高的功能。比如其重写了int read();和int read(char[], int, int);方法,并增强提供了读取行的方法String readLine();方法。
//自己实现一个Reader的增强类MyBufferedReader
import java.io.*; class MyBufferedReader extends Reader { private Reader fr = null; MyBufferedReader(Reader fr) { this.fr = fr; } public String MyReadLine()throws IOException { StringBuilder sb = new StringBuilder(); int ch; while((ch = fr.read()) != -1) { if(ch == '\r') continue; if(ch == '\n') return sb.toString(); sb.append((char)ch); } if(sb.length() != 0) return sb.toString(); return null; } public void close()throws IOException { fr.close();//使用子类自己的close()方法 } p 4000 ublic int read(char[] cbuf, int off, int length)throws IOException { return fr.read(cbuf, off, length); } }4.InputStream、OutputStream
字节流的操作和字符流大同小异,只不过字符流操作的文本,字节流可以操作图片、mp3等媒体文件,其使用的范围更加的广泛。下面通过一个拷贝mp3的例子来说明下。
//拷贝mp3
import java.io.*; class Copy_TuPian { public static void main(String[] args)throws IOException { BufferedInputStream fis = new BufferedInputStream(new FileInputStream("E:\\Code\\如果没有你.mp3")); BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream("E:\\Code\\Copy_如果没有你.mp3")); byte[] buf = new byte[1024]; int len; while((len = fis.read(buf)) != -1) { fos.write(buf, 0, len); } fis.close(); fos.close(); } }5.InputStreamReader、OutputstreamWriter
转换流可以将字节转换成字符,原因在于,其将获得到的字节通过查编码表获取到指定对应字符,其就是基于 字节流 + 编码表,没有转换就没有字符流,所以凡是操作设备上的文本数据,涉及编码转换都必须使用转换流。
转换流的一个最特殊的运用就是标准输入和标准输出。
标准输入(键盘录入):BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
标准输出(屏幕):BufferedWrite bufw = new BufferedWriter(new OutputStreamWriter(System.out));
四、总结-流操作规律
通过以上的学习,我们不难发现,流就是读和写的操作,明确源和目的之后,就很好操作了。
--明确源和目的地
数据源:就是从哪里读取数据,可以使用的两个体系:InputStream、Reader
目的地:就是要往哪里写入数据,可以使用的两个体系为:OutputStream、Writer
--操作的数据是否纯文本
如果是:读-Reader,写-Writer
若不是:读-InputStream,写-OutputStream
--虽然明确了体系,但是体系中有太多的对象,到底用哪个?
数据源对应的设备:硬盘(File)、内存(数组)、键盘(System.in)
目的地对应的设备:硬盘(File)、内存(数组)、控制台(System.out)
--需要在基本操作上附加其他功能吗?比如缓冲
如果需要就进行装饰
----------------------
ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
相关文章推荐
- 黑马程序员_Java基础——IO框架(下)(第6篇)
- 黑马程序员-java基础 io字节流
- 黑马程序员_Java基础_集合框架1
- 黑马程序员----JAVA基础之junit测试框架
- 黑马程序员-----java基础十五(java之集合框架)
- 黑马程序员 java基础之IO总结
- 黑马程序员---Java基础--14天(集合框架之一)
- 黑马程序员_Java基础集合框架
- 黑马程序员---java基础之IO(字符流和字节流)
- 黑马程序员——java基础之IO
- 黑马程序员-java基础 io其他类
- 黑马程序员_Java基础_集合框架工具类相关应用
- 黑马程序员 java基础之IO笔记
- (黑马程序员)Java基础加强(第一天)4.Junit测试框架
- 黑马程序员---Java基础--15天(集合框架之二)
- 黑马程序员_java编程基础15 集合框架
- 黑马程序员_java编程基础16 集合框架2
- 黑马程序员_Java基础Day14_集合框架
- 黑马程序员_java基础视频第21天_JavaIO续集3
- 黑马程序员----JAVA基础集合框架_迭代器