当前位置:   article > 正文

JavaSe基础XX18——IO流_2_字符流缓冲区

xx18

*11-IO流(字符流-缓冲区-解释)

//创建一个临时容器,用于缓存读取到的字符。
char[] buf = new char[BUFFER_SIZE];//这就是缓冲区。 是自己new出来的。提高效率

Java就把这个缓冲区封装成一个对象,其实把缓冲区封装成对象,就是在一个类中封装一个数组。

对于读和写都封装成了对象。

IO包中:








*12-IO流(字符流-缓冲区-BufferedWriter)

之前缓冲区,是自己new出来的,

系统给了,bufferwriter,bufferreader、





缓冲区创建的时候,必须指定要缓存的对象,也就是Writer对象。


以前这样写:



提高效率,就要加缓冲区了:



注意:关掉buffer的时候也会把流给关掉。



  1. package cn.itcast.p2.io.charstream.buffer;
  2. import java.io.BufferedWriter;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. public class BufferedWriterDemo {
  6. private static final String LINE_SEPARATOR = System.getProperty("line.separator");
  7. /**
  8. * @param args
  9. * @throws IOException
  10. */
  11. public static void main(String[] args) throws IOException {
  12. FileWriter fw = new FileWriter("buf.txt");
  13. //为了提高写入的效率。使用了字符流的缓冲区。
  14. //创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联
  15. BufferedWriter bufw = new BufferedWriter(fw);
  16. //使用缓冲区的写入方法将数据先写入到缓冲区中。
  17. // bufw.write("abcdefq"+LINE_SEPARATOR+"hahahha"); 效果和bufw.newLine();一样,其实调用的也是system.
  18. // bufw.write("xixiixii");
  19. // bufw.newLine();
  20. // bufw.write("heheheheh");
  21. for(int x=1; x<=4; x++){
  22. bufw.write("abcdef"+x);
  23. bufw.newLine();
  24. bufw.flush();
  25. }
  26. //使用缓冲区的刷新方法将数据刷目的地中。
  27. // bufw.flush();
  28. //关闭缓冲区。其实关闭的就是被缓冲的流对象。
  29. bufw.close();
  30. // fw.write("hehe");
  31. // fw.close();
  32. }
  33. }

*13-IO流(字符流-缓冲区-BufferedReader)

读怎么读?

以前的读法:

  1. public static void demo() throws FileNotFoundException, IOException {
  2. FileReader fr = new FileReader("buf.txt");
  3. char[] buf = new char[1024];
  4. int len = 0;
  5. while((len=fr.read(buf))!=-1){
  6. System.out.println(new String(buf,0,len));
  7. }
  8. fr.close();
  9. }


新的:





读文本:可以一个一个字符读,也可以读完放数组中,也可以一行一行读。



  1. public class BufferedReaderDemo {
  2. /**
  3. * @param args
  4. * @throws IOException
  5. */
  6. public static void main(String[] args) throws IOException {
  7. FileReader fr = new FileReader("buf.txt");
  8. BufferedReader bufr = new BufferedReader(fr);
  9. String line = null;
  10. while((line=bufr.readLine())!=null){
  11. System.out.println(line);
  12. }
  13. /*
  14. String line1 = bufr.readLine();
  15. System.out.println(line1);
  16. String line2 = bufr.readLine();
  17. System.out.println(line2);
  18. String line3 = bufr.readLine();
  19. System.out.println(line3);
  20. String line4 = bufr.readLine();
  21. System.out.println(line4);
  22. String line5 = bufr.readLine();
  23. System.out.println(line5);
  24. */
  25. bufr.close();
  26. }


*14-IO流(字符流-缓冲区-BufferedReader-readLine方法原理)


read ,read()和read(char[])  ——硬盘里面读


bufferread 重写了父类的read()和read(char[]) ——缓冲区读,内存操作,快。


bufr.read():一次只能读一个字符;

bufr.readLine():一次读一行。








*15-IO流(字符流-缓冲区-复制文本文件)

一种方法:


第二种方法:读一行,写一行。




这样会只存在一行里面。



  1. package cn.itcast.p3.io.charstream.buffer.test;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.FileNotFoundException;
  5. import java.io.FileReader;
  6. import java.io.FileWriter;
  7. import java.io.IOException;
  8. public class CopyTextByBufTest {
  9. /**
  10. * @param args
  11. * @throws IOException
  12. */
  13. public static void main(String[] args) throws IOException {
  14. FileReader fr = new FileReader("buf.txt");
  15. BufferedReader bufr = new BufferedReader(fr);
  16. FileWriter fw = new FileWriter("buf_copy.txt");
  17. BufferedWriter bufw = new BufferedWriter(fw);
  18. String line = null;
  19. while((line=bufr.readLine())!=null){
  20. bufw.write(line);
  21. bufw.newLine();
  22. bufw.flush();
  23. }
  24. /*
  25. int ch = 0;
  26. while((ch=bufr.read())!=-1){
  27. bufw.write(ch);
  28. }
  29. */
  30. bufw.close();
  31. bufr.close();
  32. }
  33. }


*16-IO流(字符流-缓冲区-自定义MyBufferedReader-read方法)



1.read方法:


  1. /**
  2. * 自定义的读取缓冲区。其实就是模拟一个BufferedReader.
  3. *
  4. * 分析:
  5. * 缓冲区中无非就是封装了一个数组,
  6. * 并对外提供了更多的方法对数组进行访问。
  7. * 其实这些方法最终操作的都是数组的角标。
  8. *
  9. * 缓冲的原理:
  10. * 其实就是从源中获取一批数据装进缓冲区中。
  11. * 在从缓冲区中不断的取出一个一个数据。
  12. *
  13. * 在此次取完后,在从源中继续取一批数据进缓冲区。
  14. * 当源中的数据取光时,用-1作为结束标记。
  15. *
  16. *
  17. * @author Administrator
  18. *
  19. */
  20. public class MyBufferedReader extends Reader {
  21. private Reader r;
  22. //定义一个数组作为缓冲区。
  23. private char[] buf = new char[1024];
  24. //定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。
  25. private int pos = 0;
  26. //定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。
  27. private int count = 0;
  28. MyBufferedReader(Reader r){
  29. this.r = r;
  30. }
  31. /**
  32. * 该方法从缓冲区中一次取一个字符。
  33. * @return
  34. * @throws IOException
  35. */
  36. public int myRead() throws IOException{
  37. if(count==0){
  38. count = r.read(buf);
  39. pos = 0;
  40. }
  41. if(count<0)
  42. return -1;
  43. char ch = buf[pos++];
  44. count--;
  45. return ch;
  46. /*
  47. //1,从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。
  48. if(count==0){
  49. count = r.read(buf);
  50. if(count<0)
  51. return -1;
  52. //每次获取数据到缓冲区后,角标归零.
  53. pos = 0;
  54. char ch = buf[pos];
  55. pos++;
  56. count--;
  57. return ch;
  58. }else if(count>0){
  59. char ch = buf[pos];
  60. pos++;
  61. count--;
  62. return ch;
  63. }*/
  64. }




*17-IO流(字符流-缓冲区-自定义MyBufferedReader-readLine方法)

readLine()的实现。

  1. public String myReadLine() throws IOException{
  2. StringBuilder sb = new StringBuilder();
  3. int ch = 0;
  4. while((ch = myRead())!=-1){
  5. if(ch=='\r')
  6. continue;
  7. if(ch=='\n')
  8. return sb.toString();
  9. //将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。
  10. sb.append((char)ch);
  11. }
  12. if(sb.length()!=0)
  13. return sb.toString();
  14. return null;
  15. }

MyBufferReaderDemo:

  1. package cn.itcast.p4.io.charstream.mybuffer;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.util.Collections;
  5. import java.util.HashMap;
  6. public class MyBufferedReaderDemo {
  7. /**
  8. * @param args
  9. * @throws IOException
  10. */
  11. public static void main(String[] args) throws IOException {
  12. FileReader fr = new FileReader("buf.txt");
  13. MyBufferedReader bufr = new MyBufferedReader(fr);
  14. String line = null;
  15. while((line=bufr.myReadLine())!=null){
  16. System.out.println(line);
  17. }
  18. bufr.myClose();
  19. Collections.reverseOrder();
  20. HashMap map = null;
  21. map.values();
  22. }
  23. }

MyBufferReader:

  1. package cn.itcast.p4.io.charstream.mybuffer;
  2. import java.io.FileReader;
  3. import java.io.IOException;
  4. import java.io.Reader;
  5. /**
  6. * 自定义的读取缓冲区。其实就是模拟一个BufferedReader.
  7. *
  8. * 分析:
  9. * 缓冲区中无非就是封装了一个数组,
  10. * 并对外提供了更多的方法对数组进行访问。
  11. * 其实这些方法最终操作的都是数组的角标。
  12. *
  13. * 缓冲的原理:
  14. * 其实就是从源中获取一批数据装进缓冲区中。
  15. * 在从缓冲区中不断的取出一个一个数据。
  16. *
  17. * 在此次取完后,在从源中继续取一批数据进缓冲区。
  18. * 当源中的数据取光时,用-1作为结束标记。
  19. *
  20. *
  21. * @author Administrator
  22. *
  23. */
  24. public class MyBufferedReader extends Reader {
  25. private Reader r;
  26. //定义一个数组作为缓冲区。
  27. private char[] buf = new char[1024];
  28. //定义一个指针用于操作这个数组中的元素。当操作到最后一个元素后,指针应该归零。
  29. private int pos = 0;
  30. //定义一个计数器用于记录缓冲区中的数据个数。 当该数据减到0,就从源中继续获取数据到缓冲区中。
  31. private int count = 0;
  32. MyBufferedReader(Reader r){
  33. this.r = r;
  34. }
  35. /**
  36. * 该方法从缓冲区中一次取一个字符。
  37. * @return
  38. * @throws IOException
  39. */
  40. public int myRead() throws IOException{
  41. if(count==0){
  42. count = r.read(buf);
  43. pos = 0;
  44. }
  45. if(count<0)
  46. return -1;
  47. char ch = buf[pos++];
  48. count--;
  49. return ch;
  50. /*
  51. //1,从源中获取一批数据到缓冲区中。需要先做判断,只有计数器为0时,才需要从源中获取数据。
  52. if(count==0){
  53. count = r.read(buf);
  54. if(count<0)
  55. return -1;
  56. //每次获取数据到缓冲区后,角标归零.
  57. pos = 0;
  58. char ch = buf[pos];
  59. pos++;
  60. count--;
  61. return ch;
  62. }else if(count>0){
  63. char ch = buf[pos];
  64. pos++;
  65. count--;
  66. return ch;
  67. }*/
  68. }
  69. public String myReadLine() throws IOException{
  70. StringBuilder sb = new StringBuilder();
  71. int ch = 0;
  72. while((ch = myRead())!=-1){
  73. if(ch=='\r')
  74. continue;
  75. if(ch=='\n')
  76. return sb.toString();
  77. //将从缓冲区中读到的字符,存储到缓存行数据的缓冲区中。
  78. sb.append((char)ch);
  79. }
  80. if(sb.length()!=0)
  81. return sb.toString();
  82. return null;
  83. }
  84. public void myClose() throws IOException {
  85. r.close();
  86. }
  87. @Override
  88. public int read(char[] cbuf, int off, int len) throws IOException {
  89. return 0;
  90. }
  91. @Override
  92. public void close() throws IOException {
  93. }
  94. }

*18-IO流(字符流-缓冲区-装饰设计模式)


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


  1. package cn.itcast.p5.wrapper;
  2. public class PersonDemo {
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. Person p = new Person();
  8. // p.chifan();
  9. NewPerson p1 = new NewPerson(p);
  10. p1.chifan();
  11. NewPerson2 p2 = new NewPerson2();
  12. p2.chifan();
  13. }
  14. }
  15. class Person{
  16. void chifan(){
  17. System.out.println("吃饭");
  18. }
  19. }
  20. //这个类的出现是为了增强Person而出现的。
  21. class NewPerson{
  22. private Person p ;
  23. NewPerson(Person p){
  24. this.p = p;
  25. }
  26. public void chifan(){
  27. System.out.println("开胃酒");
  28. p.chifan();
  29. System.out.println("甜点");
  30. }
  31. }
  32. class NewPerson2 extends Person{
  33. public void chifan(){
  34. System.out.println("开胃酒");
  35. super.chifan();
  36. System.out.println("甜点");
  37. }
  38. }

装饰好呢?还是继承好呢?

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


有什么区别呢?


*19-IO流(字符流-缓冲区-装饰设计模式和继承的区别)



有什么区别呢?


首先有一个继承体系。
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:用于提高效率。

装饰比继承灵活。


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


装饰设计模式。


*20-IO流(字符流-缓冲区-LineNumberReader)



















声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/247043
推荐阅读
相关标签
  

闽ICP备14008679号