黑马程序员技术交流社区

标题: 这两天把学过的都总结总结 IO总结 [打印本页]

作者: 齐银春    时间: 2012-11-26 13:59
标题: 这两天把学过的都总结总结 IO总结
在基础班学到的:
字节流两个基类:
InputStream(字节输入流)  OutputStream(字节输出流)
字符流两个基类:
Reader(字符输入流) Writer(字符输出流)
学习io流体系:看顶层(父类共性功能),用底层(子类具体对象)。
该体系的一个好处就是:
每个子类的后缀名都是所属体系的父类的名称,很容易区分所属的体系。
而且每一个子类前缀名都是该子类对象的功能体现。
这样我们在使用io体系中的对象时,就非常容易查找了。

//需求:将一个段文字数据写入到硬盘上.
思路:
1,一段文字就是字符串数据。
2,写到硬盘上,从哪到哪呢?字符串数据在内存中,写到硬盘上,哎呦!这不是将内存中的数据搞到硬盘上,
这就涉及到了设备之间的数据处理。就要用到IO技术。
既然是从内存到硬盘,应该是输出流。
3,对于文字而言,io中提供了便捷的操作,比如字符流。
4,结合两者,需要输出流,需要字符流,可是使用字符输出流。Writer
5,具体用哪个子类对象呢?硬盘上用于存储数据的体现:文件。希望可以在Writer体系中知道可以操作文件的Writer对象。
找到了具体的对象FileWriter.
小插曲。
两个写入流往一个文件写入数据,就如同,两个人在同时往一张纸写字一样。
都是从头开始写,第二人写的会将第一个人的文字覆盖掉。

--------------
//需求:读取一个硬盘上的文本文件,将数据打印到控制台上。
思路:
1,读取无非就是将硬盘的数据弄到内存中。要使用到输入流。
2,既然是文字,可以使用字符流,一综合使用字符输入流,该体系时Reader.
3,既然要读取一个文本文件。可以使用 FileReader:用于读取字符文件的便捷类。

------------------
字符流的缓冲区。
BufferedReader
BufferedWriter
缓冲区给给流的操作动作(读写)提高效率.所以缓冲区的对象建立必须要有流对象。

---------------------
字符流:
FileReader
FileWriter
BufferedReader
BuffereWriter
字节流。
InputStream  OutputStream
FileInputStream FileOutputStream
BufferedInputStream BufferedOutputStream

转换流:
字节流--->字符流的桥梁。InputStreamReader
字符流--->字节流的桥梁。OutputStreamWriter
---------------------------------------
流的操作规律:
在进行数据操作时,IO包中提供了N多对象不同功能来操作设备上的数据。
在实际开发时,到底用哪个流对象来完成数据处理呢?
这是我们最为苦恼的事情。
如何明确具体用哪个流对象呢?

规律就是四个明确?
1,明确源和目的。
源:InputStream   Reader 一定是被读取的。
目的:OutputStream  Writer 一定是被写入的。

2,处理的数据是否是纯文本的数据?
是:使用字符流。Reader Writer
否:使用字节流。 InputStream OutputStream

如果是源并且是纯文本,Reader  如果是目的并且是纯文本,Writer
  到这里,两个明确确定完,就可以确定出要使用哪个体系。
接下来,就应该明确具体这个体系要使用哪个具体的对象。
3,明确数据所在的设备:
源设备:
  键盘(System.in)    硬盘(FileXXX)FileReader FileInputStream
  内存(数组)ByteArrayInputStream CharArrayReader StringReader
  网络(Socket)
目的设备:
  显示器(控制台System.out)
  硬盘(FileXXX)FileWriter FileOutputStream
  内存(数组)ByteArrayOutputStream CharArrayWriter StringWriter
  网络(Socket)

具体使用哪个对象就可以明确了。

4,明确是否需要额外功能?
1,是否需要高效?缓冲区Buffered 四个。
2,是否需要转换?转换流 InputStreamReader OutputStreamWriter
3,是否操作基本数据类型? DataInputStream  DataOutputStream
4,是否操作对象(对象序列化)? ObjectInputStream ObjectOutputStream
5,需要对多个源合并吗? SequenceInputStream
6,需要保证数据的表现形式到目的地吗? PrintWriter  
如果数据有规律,并且源和目的都是file,需要随机访问时,可以使用RandomAccessFile工具类。

-------------------
实际需求:
需求1:复制一个文本文件。
1,明确源和目的:既有源,又有目的。
  源:InputStream Reader
  目的:OutputStream Writer.
2,明确是否是纯文本?是!
  源:Reader
  目的:Writer
3,明确具体设备:
  源:
   硬盘(file)
  目的:
   硬盘(file)
  
  源对应的体系Reader中可以操作硬盘设备的对象是 FileReader
  目的对应的体系Writer中可以操作硬盘设备的对象是FileWriter
  
直接明确具体对象并创建。
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,明确是否是纯文本?不是!
  源:InputStream     目的:OutputStream
3,明确设备:
  源:硬盘      目的:硬盘:
  FileInputStream fis = new FileInputStream("1.jpg");
  FileOutputStream fos = new FileOutputStrema("2.jpg");

需求3:读取键盘录入,存储到一个文件中。
1,明确源和目的:既有源,又有目的。
  源:InputStream Reader     目的:OutputStream Writer.
2,明确是否是纯文本?一般键盘录入的都是文字,所以是纯文本的。
  源:Reader    目的:Writer
3,明确设备:
  源:键盘。  目的:硬盘。
    具体对象
   源是:System.in.      目的是:FileWriter
   
  InputStream in = System.in;         FileWriter fw = new FileWriter("a.txt");
  对这个读写,应该这样完成,通过键盘录入读取字节数据,先不做写入操作,
  而是将字节数据临时存储,转成字符串,然后在交给fw写入。
  
  发现代码操作的起来很麻烦。有没有已有的功能可以解决这个问题啊?
4,需要额外功能吗?
  需要。必须的。        需要将键盘录入的字节转成字符。
  使用转换流。而且是 将字节-->字符的转换流对象。InputStreamReader
  
  InputStreamReader isr = new InputStreamReader(System.in);
  FileWriter fw = new FileWriter("a.txt");
   
  还需要其他功能吗?
  需要,高效。
  BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
  BufferedWriter bufw = new BufferedWriter(new FileWriter("a.txt"));
  
需求4:读取一个文本文件,显示到显示器上。
1,明确源和目的:既有源,又有目的。
  源:InputStream Reader     目的:OutputStream Writer.
2,明确是否是纯文本?是。
  源:Reader    目的:Writer
3,明确设备:
  源:硬盘。File     目的:显示器。System.out

  FileReader fr = new FileReader("a.txt");     OutputStream out = System.out;
  这已经可以完成读写了。
  通过fr读取文本到字符数组,将字符数组转成字符串,然后在将字符串转成字节数组。
  交给out输出。
  就是这个转换动作都需要自己完成。烦!
  有没有已有的功能可以解决这个问题啊?
4,需要额外功能吗?必须的。
  转换。需要将已有的字符数据转成字节。字符-->字节的桥梁 OutputStreamWriter
  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 OutputStreamWrier(System.out));
------------------------------
需求5:读取一个文本文件,将文件中文本按照指定的编码表UTF-8写入到另一个文件中。
1,明确源和目的:既有源,又有目的。
  源:InputStream Reader
  目的:OutputStream Writer.
2,明确是否是纯文本?是。
  源:Reader
  目的:Writer
3,明确设备:
  源:硬盘。File
  目的:硬盘。File

  FileReader fr = new FileReader("a.txt");
  FileWriter fw = new FileWriter("b.txt");
  
  这样做不行,满足不了需求,为什么呢?
  因为这个两个对象在操作文本数据,都是用了默认的编码表。在我的本机中默认码表是GBK.而需求中希望写入到文件的数据是按照utf-8的码表。
  其实这两个对象就是字节流+默认编码表。
  
  源对象不变。
  FileReader fr = new FileReader("a.txt");
  需要目的为指定编码表。
  这时就要用到转换流。因为转换流中可以指定具体的编码表。 需要往里传递一个字节流,而且要操作文件,FileOutputStream
  OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8");
  
  需要高效
  BufferedReader bufr = new BufferedReader(new FileReader("a.txt"));
  BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8"));

以下部分的内容,要求必须理解!
c:\\1.txt 源是一个文件也是字节数据,是不是应该使用字节流呢?

FileInputStream fis = new FileInputStream("c:\\1.txt");
InputStreamReader isr = new InputStreamReader(fis,"gbk");
isr.read();//字符。
既然是明确操作是文件,而且使用默认编码表。
可以使用InputStreamReader的子类。FileReader
FileReader fr = new FileReader("c:\\1.txt");


作者: 许庭洲    时间: 2012-11-27 07:46
值得学习ing!
作者: jonn    时间: 2012-11-27 13:19
学习学习....




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2