(十二)Core Java IO流(FileWriter,FileReader,BufferedWriter,BufferedReader)-01 (106)

 目录 :            1 ) . IO流(概述)

2 ) .  IO流(FileWriter)

3 ) .   IO流(IO异常处理方式)

4 ) .  IO流(文件的续写)

5 ) . IO流(文本文件读取方式一)

6 ) .  IO流(文本文件读取方式二)

7 ) .   IO流(文本文件读取练习)

8 ) .  IO流(拷贝文本文件)

9 ).IO流(拷贝文本文件图例)

10 ).IO流(Buffered Writer)

11 ). IO流(BufferedReader)

12 ). IO流(通过缓冲区复制文本)

13 ). IO流(readline的原理图例)

14 ). IO流(mubufferedReader)

15 ). IO流(装饰设计模式)

16 ). IO流(装饰和继承的区别)

17 ). IO流(自定义装饰类)

18 ). IO流(LineNumberReader)

19 ). IO流(MyIneNnmberReader)

20 ). IO流(字节流File读写操作)

 

     一 .  IO流(概述)

1 ) . 概述 :   (Input,Output)流

1.1 用处 : IO流用来处理设备之间的数据传输

1.2 案例 : Java对数据的操作是通过流的方式

1.3 jar包 : Java用于操作流的对象都在IO包中

1.3 分类 : 

[1] 流按照操作数据分为 : 字节流和字符流

[2] 流按照流向分为 : 输入流,输出流   

2 ) . 编码表发展史 : 

2.1  第一阶段 : ASCII  : 美国信息标准交换码 :  二进制与英文字母相对应的表 ;    

2.2 第二阶段 :  JB2312 -->GBK-->GB18030  : 信息交换汉字编码字符集 : 二进制与中文相对应的表  

2.3 第三阶段 : Unicode  : 国际标准码表  -->UTF-8 : 可变长度字符编码

3 ) .  为何会产生乱码 : 

3.1 当你用GBK的字符集写的程序到了一个UTF-8的字符集操作系统中便会出现乱码问题

4 ) . 字符流的优势  :

4.1 当你的字符集不确定是用的GBK还是UTF-8时,便可自行更改指向 -->意思就是 字符流的对象中融合的是编码表,字符流的出现是为了解决乱码问题的

5 ).IO流常用基类 : 

5.1 字节流的抽象基类 : 

[1] InputStream   

[2] OutputStream

5.2 字符流的抽象基类 : 

[1] Reader  读出 

[2] Writer  写入

ps : 由这四个类派生出来的子类名称都是以其父类名作为子类的后缀  ;  例子 : InputStream的子类FileStream  ;   Reader的子类FileReader

 

小结 :  

             1.  处理设备的方式是通过IO流实现的,处理设备的对象方法都放在IO包中
        
           2.  硬盘和内存的体现形式都是字节; 

           3. 字节流是用来处理音频,视频....的, 字符流是用来处理文字的  ;  通用是字节流, 字符流是基于字节流的

           4. 所有的子类的名字后缀名都是父类的名字
 

       二.  IO流(FileWriter)


1 ) . FileWriter :  文件写入方法, 用来对文件进行操作

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : IO流的字符串写入文件,刷新缓冲区,关闭流资源
  需求: 在硬盘上,创建一个文件并写入一些文字数据
 
  思路: 找到专门用于操作文件的writer子类对象 FileWriter : 后缀名是父类名,前椎名是该流对象的功能  -->其它类同样如此
 
       FileWriter :
       
       [1]功能 : 创建数据存放地址的文件
       
       [2]特点: 该对象一初始化就要明确被操作的文件
 
 
 */
 
 
 
 
  import java.io.*;
  class FileWriterDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                    
                    //明确数据存放的位置 ; 若该位置存在该文件,则直接覆盖;若该位置不存在该文件,则直接创建
                    
                FileWriter fw = new FileWriter("Demo.txt");
               
                //调用write方法,将字符串写入流
                fw.write("abcde");
               
               
                //调用其flush方法,将字符串从流刷新到指定文件
                fw.flush();
               
                //关闭流资源,在关闭之前会自动调用flush()刷新一次
                fw.close();
             
             
               
                /*
                flush()与close的区别 :
               
                1.flush刷新后还可写入,而close刷新后则不可写入
               
                2.flush刷新不是必须,而close关闭资源是必须存在的,否则出现IO流异常
               
                3.flush刷新是调用后刷新,而close关闭资源则也会自动调用flush刷新
                */
               
               
               
               
               
               
             
               }
  }     
 
             
 

小结 :  

             1.  数据的最常见的表现形式是文件
        
           2.  java的本质上是不能进行读写数据的,底层调用的是windows系统中的方法,调用其资源进行操作的
 


      三.  IO流(IO异常处理方式)

1 ) . IO流中try{}catch(){}finally{}正确的使用方式

2 ) . Demo:


 
 /*
 
 该节内容讲述了 :  IO异常的处理方式
 
 问题:
 
 [1] 空指针异常 -->当地址错误时,则初始化失败,则外部引用为空,而close()未做判断时会出现
 
 [2] fw 引用错误 --> 当引用和初始化都在一个代码块中,而另一个代码块需要用到其变量而调用不了时出现,解决 : 外部创建引用,内部进行初始化
 
 */
 
 
 
 
  import java.io.*;
  class FileWriterException
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[])
               { 
                    
                    
                    
                    //外部创建引用
                  FileWriter fw =null;
               
                      try
                      {
                             //内部进行初始化
                    fw=new FileWriter("Demo.txt");
                      
                       //将字符串写入流
                       fw.write("ssdfg");
                      
                    
                            
                      }//捕获异常
                      catch(IOException io)
                      {
                             System.out.println(io);
                            
                      }
                      finally
                      {
                            
                                 try
                                 {      //关闭流
                                         if(fw!=null)
                                         fw.close();
                                        
                                 }//捕获异常
                                 catch(IOException io)
                                 {
                                          System.out.println(io);
                                         
                                 }
                                 
                            
                      }
 
             
               }
  }     
 
             

 

小结 :  

             1.  但凡是跟windows上的资源发生关系的大多都会产生异常
        
           2.  有关系的代码放到一个try当中

       
 

      四. IO流(文件的续写)

1 ) . FileWriter("文件地址",true)  -->该true参数代表可对当前文件进行数据续写

2 ) . Demo:


 
 /*
 
 该节内容讲述了 :  构造函数FileWriter()中传入true代表可对当前文件进行数据续写
 
 
 */
 
 
 
 
  import java.io.*;
  class FileWriterContinue
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                    //指定数据进入的文件地址,传入的true参数代表若文件已存在,则在文件的末位进行数据续写;若文件不存在,则创建
                    FileWriter fw =new FileWriter("Demo.txt",true);
                    //将字符串写入流
                    fw.write("asdfg\r\nasdfg");//当前\r\n指换行
                    //关闭流资源,并将缓冲区的数据刷入指定文件
                    fw.close();
                    
             
             
               }
  }     
 
             


 

 
小结 :  

             1.  windows当中\r\n代表换行,而linux当中仅\n就代表换行
        
    


     五 .  IO流(文本文件读取方式一)

1 ) . 读取方式一: 通过for循环 迭代 FilerReader类中的read方法实现读取

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
 
     文本文件读取方式一 :  通过 for 循环 迭代 FileReader 类中的read方法读取
       
       
        read() : 该方法一次读一个字符,而且会自动往下读
 
 */
 
 
 
 
  import java.io.*;
  class FileReaderDemo1
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                    
                     //创建一个文件读取流对象与指定名称的文件相关联
                     //若关联的该文件不存在,则会报异常FileNOtFoundException
                    FileReader fr =new FileReader("Demo.txt");
                    
                    
                    
                    //普通版 --.读取文件数据
                    while(true)
                    {      //读取单个字符
                           int ch = fr.read();
                           //判断是否到最后一个字符
                           if(ch==-1)
                                 break;
                           //输出读到的字符
                           sop((char)ch);
                           
                    }
                    
                    
                    int ch =0;
                    
                    //优化版 -->读取文件数据
                    while((ch=fr.read())!=-1)
                    {
                           sop((char)ch);
                    }
                    
                    
                    
             
               }
  }     
 
             


 
小结 :  

             1.  切记 文件读取 当读到末尾时,会返回-1,则说明没有数据了
        
        
 

       六. IO流(文本文件读取方式二)


1 ) . 读取方式二 : 通过for循环迭代FileReader类中的read方法将数据读取到数组中,然后再一次性打印

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
 
     文本文件读取方式二 :  通过 for 循环 迭代 FileReader 类中的read方法将数据读取到数组中,然后再一次性打印
        
 
 */
 
 
 
 
  import java.io.*;
  class FileReaderDemo2
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                    
                     FileReader fr =new FileReader("Demo.txt");
                    
                     //创建一个数组,用来装数据;
                     char[] buf =new char[1024];
                    
                     int num=0;
                    
                     //将数据读到数组buf中,并且返回的是读入数据的个数-->详细见api
                    while((num = fr.read(buf))!=-1)
                    {
                           //将数组buf中0-num这个范围之间的数据转换成String类型并输出
                           sop(new String(buf,0,num));
                           
                    }
                    
                    
                    
                    
                    
             
               }
  }     
 
             



 

小结 :  

             1.  文件读取方式一是 读一个字符打印一个字符 ; 文件读取方式二是 读一个字符,存一个字符,然后 一次性打印
        
    


      七.  IO流(文本文件读取练习)

1 ) . Demo ; 


 
 /*
 
 该节内容讲述了 : 
 
      需求 : 读取一个java文件,并打印在控制台上
 
 */
 
 
 
 
  import java.io.*;
  class FileReaderDemo3
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
 
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                     //创建读对象并指定要读的文件
                     FileReader fr =new FileReader("FileWriterDemo2.java");
                    
                     //创建一个数组用来接数据
                     char[] buf =new char[1024];
                    
                     //创建一个变量,来接收数据数量
                     int num=0;
                     //将数据迭代到数组中,并判断是否到结尾,若未到结尾,则一直循环
                    while((num=fr.read(buf))!=-1)
                    {
                           //输出的数据是数组中已有范围的数据
                           sop(new String(buf,0,num));
                    }
                    
                    //关闭资源
                    fr.close();
                    
                    
             
               }
  }     
 
             


  
 

     八 IO流(拷贝文本文件)

1 ) . 拷贝文件 : 就是将对方文件的数据放入另一个文件中

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
 
      需求 :  将C盘上一个文本文件复制到D盘
        
         复制的原理: 其实就是将C盘下的文件数据存储到D盘的一个文件中
        
         实现步骤:
        
         [1] 在D盘创建一个文件,用于存储C盘文件中的数据
        
         [2] 定义读取流和C盘文件关联
        
         [3] 通过不断的读写完成数据存储
        
         [4] 关闭资源
 
 */
 
 
 
 
  import java.io.*;
  class copyText
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               { 
                           //copy_1();
                            copy_2();
               }
              
              
               //复制的方式二
               public static void copy_2()
               {
                    
                      FileWriter fw=null;
                    
                      FileReader fr=null;
                     
                      try
                      {  //读入数据的目击地
                             fw=new FileWriter("Demo_copy.txt");
                               //写出数据的起始地
                             fr=new FileReader("Demo.txt");
                            
                             //用于临时存储数据的数组
                             char[] buf = new char[1024];
                             //用于计算长度的变量
                             int len=0;
                             //取出放入数组
                             while((len=fr.read(buf))!=-1)
                             {           //从数组中取出放入目击地
                                    fw.write(buf);
                                  
                             }
                            
                            
                            
                      }
                      catch(IOException e)
                      {
                             throw new RuntimeException("读写失败");
                            
                      }
                      finally
                      {
                            
                             try
                             {
                                   if(fw!=null)
                                          fw.close();
                                  
                                  
                             }
                             catch(IOException E)
                             {
                                  
                                  
                             }
                            
                              try
                             {
                                   if(fr!=null)
                                          fr.close();
                                  
                                  
                             }
                             catch(IOException E)
                             {
                                  
                                  
                             }
                            
                      }
                     
               }
              
              
              
              
               //方式一: 读一个 存入一个
             /*   public static void copy_1() throws IOException
               {
                     
                      FileWriter fw =new FileWriter("Demo_copy.txt");
                     
                      FileReader fr  = new FileReader("Demo.txt");
                     
                      int num=0;
                     
                      while((num=fr.read())!=-1)
                      {
                            
                             fw.write(num);
                            
                      }
                     
                     fw.close();
                     fr.close();
                     
                     
               } */
  }     
 
             
 

  
          

     九 .  IO流(拷贝文本文件图例)

1 ) . 图例没有,听解说吧


2 ) . 方式 : 

2.1 我们通过FileWriter()对象确定目击地, FileReader()确定起始地

2.2 我们通过read()方法将数据从起始地地写入 第三方数组中 ,而后通过Write() 方法将数据从第三方数组中写入到  目击地

2.3 我们 通过 Try()catch(){}finally{} 捕获异常,通过 close 关闭资源,通过外部引用,内部实例化的方式实现对象从局部到内部


  小结 :  

             1.  复制的过程就是数据的导出导入的过程
        
     
 

       十. .IO流(Buffered Writer)


1 ) . 简述  : BufferedWriter :  

1.1  功能 :  缓冲区的出现提高了对数据的读写效率

1.2 对应类 : 

[1] BufferedWriter

[2] BufferedReader

1.3  注意 :  缓冲区要结合流才可使用,他在流的基础上对流的功能进行了增强

 

2 ) . Demo : 


 
 /*
 
 该节内容讲述了 : 
 
      FufferedWriter : 
        
         [1] 功能 : 该类就是为了提高字符的写入效率,我们称之为缓冲技术
         [2] 方式 : 只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
         [3] 注意 : 在使用缓冲区之前首先得有流对象,因为缓冲区是对流对象操作的
        
         newLine() :  该方法是跨平台换行符 ,  无论是在linux还是windows 都有效  -->常规window中用\r\n ,linux中用\n  ,此方法解决了兼容
       
 */
 
 
 
 
  import java.io.*;
 
  class BufferedWriterDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
                           //创建一个写入流对象
                            FileWriter fw =new FileWriter("Demo.txt");
                           
                           
                            //创建一个写入缓冲区,写入数据
                            BufferedWriter bw = new BufferedWriter(fw);
                           
                            //冲入写入
                            for(int i=0;i<=5;i++)
                                  {
                                         //写入数据-->先写入到缓冲区,
                                               bw.write("asdfg"+i);
                                               //换行
                                               bw.newLine();
                                               //刷新
                                               bw.flush();
                                        
                                  }
                           
                           
                           
                           
                           
                           //将数据从缓冲区刷新到流对象指定的地址中 -->用到缓冲区就得刷新
                           bw.flush();
                           
                           //关闭流对象
                           bw.close();  //关闭缓冲区的对象也就是关闭流对象
                           
                           
                           
                           
               }
              
       
  }     
 
             


 

小结 :  

             1.  读写效率的提高有利于优化我们程序的性能
        
           2.  缓冲区就是一次性写入到缓冲区,然后从缓冲区一次性读出到指定内存的数据临时存放地

           3. 关闭缓冲区就是在关闭缓冲区当中的流对象

           4. 当报错找不到符号的两个原因,一是没导包 .二就是 类名是关键字


      十一. IO流(BufferedReader)

1 ) . BufferedReader -->文件读取缓冲区,内提供了每次读一行的方法
    
2 ) . Demo :


 
 /*
 
 该节内容讲述了 : 
 
      BufferedReader :   字符读取流缓冲区
        
         [1] 功能 : 该类就是为了提高字符的读出效率,我们称之为缓冲读取技术
         [2] 方式 : 只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
         [3] 注意 : 在使用缓冲区之前首先得有流对象,因为缓冲区是对流对象操作的
        
        
         readLine(): 该缓冲区提供了此方法用来一次读一行,方便于对数据的读取 ; 当返回null时,表示读到文件末尾
        
       
       
 */
 
 
 
 
  import java.io.*;
 
  class BufferedReaderDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
                     //创建一个读取流与相应文件相关联
                     FileReader fr = new FileReader("Demo.txt");
                    
                    
                     //创建一个读取流缓冲区将数据(字符读取流对象)作为参数放入缓冲区的构造函数
                     BufferedReader br = new BufferedReader(fr);
                    
                     //读一行
                     String s1 = br.readLine(); //该方法可用来一次读一行
                    
                 sop(s1);
                    
                     //读全部
                     String str =null;
                     //将每行读出并赋给str,来判断是否读到末尾,未到末尾则一直循环读取
                     while((str=br.readLine())!=null)
                     {
                           
                            sop(str);
                     }
       
                           
                           
               }
              
       
  }     
 
             
 
小结 :  

             1.  一次读一个vs一次读一行  ;     读一次写一次   vs  读一次存一次写一次 
        
     
 

     十二 .IO流(通过缓冲区复制文本)

1 ) . 方式 : 数据放入读流对象,读流对象数据再放入读缓冲区,读缓冲区再读出,写缓冲区写入流缓冲区,写入流缓冲区再写入写流对象

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
 
     需求:通过一个缓冲区复制一个.java文件
       
        BufferedReader  FileReader   一个读
        BufferedWriter  FileWriter   一个写
       
 */
 
 
 
 
  import java.io.*;
 
  class BufferedDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
              
               //外部建立引用,内部实例化的方式
               BufferedReader br =null;
              
               BufferedWriter bw =null;
              
               try
               {
                     
                      //将文件读取流的数据放入到读缓冲区流中   -->用来读
                    br = new BufferedReader(new FileReader("BufferedDemo.java"));
                    
                    //将文件写入流的数据放入到写缓冲区流中   -->用来写
                    bw =new BufferedWriter(new FileWriter("BufferedDemo_copy.txt"));
                    
                           String str = null;
                    //通过文件读取流将数据按一行的方式读到临时变量str中,并判断是否读到末尾
                    while((str= br.readLine())!=null)
                    {
                           //通过文件写入流将数据按一行的方式写入到写入流指定位置
                            bw.write(str);
                            //缓冲区中的方法:换行
                            bw.newLine();
                            //刷新
                            bw.flush();
                           
                    }
                    
               }//捕获异常
               catch(IOException e)
               {
                      throw new RuntimeException("读取异常");
                     
               }
               finally
               {
                     
                      try
                      {
                            if(br!=null)
                             br.close();
                     
                      }catch(IOException e)
                      {
                              throw new RuntimeException("读写失败");
                            
                      }
                     
                       try
                      {
                            if(bw!=null)
                             br.close();
                     
                      }catch(IOException e)
                      {
                              throw new RuntimeException("读写失败");
                            
                      }
                    
                     
                     
               }
              
              
             
                    
                    
             
                    
                    
                    
                    
                           
                           
               }
              
       
  }     
 
             


 


 
小结 :  

             1.  两个流之间本质上没有什么关系,让他们产生关系的是中转站
        
           2.  复制数据无非是中转站来回切换

      
          

     十三 .  IO流(readline的原理图例)


1 ) . ReadLine() : 该方法通过 读数据时先临时 存储到 数组内, 根据 \r换行符来判断是否到行末, 当到达行末时 将 数组内数据一次读入的方式实现读取一行

2 ) . 理解 :  读一行的底层最终都是在硬盘上一个一个读取,能实现读一行因为 像喝水似的,先弄个容器,一直读入,满了再读出 一个原理

 
 

       十四. .IO流(mybufferedReader)


1 ) . mybufferedReader : 自定义缓冲区将流对象放入自定义类中进行操作,它有的方法就引用,他没的方法就自造

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
 
      自定义缓冲区 :将相应的流对象放入自定义缓冲区中进行操作
        
        
       
       
       
 */
 
 
 
 
  import java.io.*;
 
  class MyBufferedReader
  {
         private FileReader fr;
        
         //将读流对象放入构造函数
         MyBufferedReader(FileReader fr)
         {
              
               this.fr=fr;
              
         }
         //读一行
         public String myReadLine() throws       IOException
         {
               //数据存储地
               StringBuilder sb =new StringBuilder();//定义一个临时容器,因为最终要将数据变成字符串
              
               //数据量检测变量
               int ch =0 ;
              
               //读入
               while((ch=fr.read())!=-1)
               {
                     
                      if(ch=='\r')
                             continue;
                      if(ch=='\n')
                             return sb.toString();
                      else
                             sb.append((char)ch);
                     
                     
               }
               //这句是用来读取最后一行的
              if(sb.length()!=0)
                     return sb.toString();
              
               return null;
              
              
              
         }
         //关闭流
         public void myClose() throws IOException
         {
              
               fr.close();
              
         }
        
 
        
  }
 
 
  class MyBufferedReaderDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
                    
                    FileReader fr =new FileReader("Demo.txt");
                    
                    
                    //创建自定义缓冲区
                    MyBufferedReader mf = new MyBufferedReader(fr);
                    
 
                    String str =null;
                    //按行读取
                    while ((str=mf.myReadLine())!=null)
                    {
 
                                 sop(str);
                                 
                           
             
                    }
                    
             
                    
                    mf.myClose();
                    
                    
              
             
              
             
       
               }
              
       
  }     
 
             



 

小结 :  

             1.  自定义类时,要明确构造函数 ; 自定义方法时,要明确参数和返回值  '以上自定义缓冲区的方式是 装饰设计模式'


  2. bufferedReader类事实上就是FileReader类的增强,
  


      十五. IO流(装饰设计模式)

1 ) . 装饰设计模式 在 工作当中对 已有项目进行功能拓展,或者进行 功能加强时使用

2 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
   
       装饰设计模式 :  拓展功能时使用
       
       何时用>? 当想要对已有的对象进行功能增强时,那么可自定义类,将已有对象传入,基于已有的功能而后进行拓展提供加强功能,那么这个自定义类成为装饰类
       
       方式?  装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供加强功能
        
        
       
       
       
 */
 
 
 
 
  import java.io.*;
 
 
  //基础类
  class Son
  {
        
         public void eat()
         {
              
                System.out.println("吃西餐");
         }
        
        
  }
  //加强类
  class Super
  {
        
         private Son son;
        
         Super(Son son)
         {
               this.son=son;
         }
        
         public void superEat()
         {
               System.out.println("来一杯");
               son.eat();
               System.out.println("来一根");
              
         }
        
        
        
  }
 
 
 
  class DecorateDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
                    
             
                    
                            Son son =new Son();
                           
                            Super su =new Super(son);
                           
                            su.superEat();
              
             
       
               }
              
       
  }     
 
             


 

小结 :  

             1.  基于原有的元素通过不断优化完善迭代出新产品的方式是装饰设计模式
        
      
          
 

     十六 .IO流(装饰和继承的区别)

1 ) . Demo:


 
 /*
 
 该节内容讲述了 : 
   
       装饰设计模式与继承的区别?
       
       通过继承拓展类功能产生的体系:  -->继承是通过每个需要增强的类都在实现个子类然后进行增强
       
       MyReader //用于读取数据的类
             -|MyTextReader
                    -|MyBufferedTextReader
             -|MyMedioReader
                    -|MyBufferedMedioReader
             -|MyViewReader
                    -|MyBufferedViewReader
             -|MyDataReader
                    -|MyBufferedDataReader
                    
                    
             评论:  以上这个类扩展性极差,因此我们可通过找到其参数的共同类型,通过多态的形式提高扩展性,见如下   
       
        通过装饰模式拓展类功能产生的体系:  -->装饰是通过实现一个公地 , 灵活的对自己体系中的类以参数的形式传入增强
       
        MyReader
             -|MyTextReader      
             -|MyMedioReader     
             -|MyViewReader
             -|MyDataReader
             -|MyBufferReader   //该类是用来为前三个类进行增强的装饰类  ,也就相当于 公地 ,谁需要谁拿去用 ,通用
                    
       
       
        总结 :一个是继承方式 ,一个是组合方式(你中有我,我中有你),指装饰
       
        比较 : 装饰,模式比继承更灵活,避免了继承体系的臃肿; 
        装饰模式比继承模式更易拓展,避免了继承体系中高耦合的关系
       
        ps:装饰类因为为增强其它类的功能,因此方法是其他类的方法更完善的方法,通常装饰类和被装饰类都属于一个体系当中的
       
       
       
 */
 
 
 
 
  import java.io.*;
 
 
  //基础类
  class Son
  {
        
         public void eat()
         {
              
                System.out.println("吃西餐");
         }
        
        
  }
 
  //装饰加强类
  class Super
  {
        
         private Son son;
        
         Super(Son son)
         {
               this.son=son;
         }
        
         public void superEat()
         {
               System.out.println("来一杯");
               son.eat();
               System.out.println("来一根");
              
         }
        
        
        
  }
 
 
 
  class DecorateDemo
  {     
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              }  
             
       
               //主方法
                public static void main(String args[]) throws IOException
               {    
                    
             
                    
                            Son son =new Son();
                           
                            Super su =new Super(son);
                           
                            su.superEat();
              
             
       
               }
              
       
  }     
 
             



2 ) . 继承是用来在同一个体系父类与子类方法同用而来;而装饰是用来在同一个体系当中为增强不同子类而存在的; 

3 ) .  功能方法增强的方式有三种 : 一种是继承 ,一种是 装饰 ,一种是 接口  

 
小结 :  

             1.  当采用继承体系去拓展功能时,会出现 臃肿和扩展性低的问题
        
      
          
     十七 .IO流(自定义装饰类)

1 ) . 自定义装饰类其实就是增强类, 想增强哪个类,先继承那个类的顶级类,将顶级类作为参数传入装饰类中,然后实现顶级类的抽象方法,然后对已有方法进行增强即可

2 ) . Demo:


/*
 
 该节内容讲述了 :
 
      自定义缓冲区 :将相应的流对象放入自定义缓冲区中进行操作  -->完善后的  -->继承reader作为他的体系
       
       
      
      
      
 */
 
 
 
 
  import java.io.*;
 
  class MyBufferedReader extends Reader
  {
         private Reader fr;
       
         //将读流对象放入构造函数
         MyBufferedReader(Reader fr)
         {
             
               this.fr=fr;
             
         }
         //读一行
         public String myReadLine() throws       IOException
         {
               //数据存储地
               StringBuilder sb =new StringBuilder();//定义一个临时容器,因为最终要将数据变成字符串
             
               //数据量检测变量
               int ch =0 ;
             
               //读入
               while((ch=fr.read())!=-1)
               {
                    
                      if(ch=='\r')
                             continue;
                      if(ch=='\n')
                             return sb.toString();
                      else
                             sb.append((char)ch);
                    
                    
               }
               //这句是用来读取最后一行的
              if(sb.length()!=0)
                     return sb.toString();
             
               return null;
             
             
             
         }
             
              /*
             
                    覆盖reader类中的抽象方法
              */
                 //关闭流
         public void close() throws IOException
         {
             
               fr.close();
             
         }
        
              public int read(char[] cbuf, int off, int len)
              {
                     return read(cbuf, off,len) ;
                    
              }
             
             
             
             
         //关闭流
         public void myClose() throws IOException
         {
             
               fr.close();
             
         }
       
 
       
  }
 
 
  class MyBufferedReaderDemo
  {    
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              } 
            
      
               //主方法
                public static void main(String args[]) throws IOException
               {   
                   
                    FileReader fr =new FileReader("Demo.txt");
                   
                   
                    //创建自定义缓冲区
                    MyBufferedReader mf = new MyBufferedReader(fr);
                   
 
                    String str =null;
                    //按行读取
                    while ((str=mf.myReadLine())!=null)
                    {
 
                                 sop(str);
 
            
                    }
                   
            
                   
                    mf.myClose();
                   
                   
             
            
             
            
      
               }
             
      
  }    
 
            


 
 
小结 :  

             1.  当继承父类时,父类中的抽象方法必须得实现
        
      
          
     十八 .IO流(LineNumberReader)

1 ) . LineNumberReader : 可以设置行号获取行号的包装类

2 ) . Demo:


/*
 
 该节内容讲述了 :
 
      自定义缓冲区 :将相应的流对象放入自定义缓冲区中进行操作  -->完善后的  -->继承reader作为他的体系
       
       
      
      
      
 */
 
 
 
 
  import java.io.*;
 
  class MyBufferedReader extends Reader
  {
         private Reader fr;
       
         //将读流对象放入构造函数
         MyBufferedReader(Reader fr)
         {
             
               this.fr=fr;
             
         }
         //读一行
         public String myReadLine() throws       IOException
         {
               //数据存储地
               StringBuilder sb =new StringBuilder();//定义一个临时容器,因为最终要将数据变成字符串
             
               //数据量检测变量
               int ch =0 ;
             
               //读入
               while((ch=fr.read())!=-1)
               {
                    
                      if(ch=='\r')
                             continue;
                      if(ch=='\n')
                             return sb.toString();
                      else
                             sb.append((char)ch);
                    
                    
               }
               //这句是用来读取最后一行的
              if(sb.length()!=0)
                     return sb.toString();
             
               return null;
             
             
             
         }
             
              /*
             
                    覆盖reader类中的抽象方法
              */
                 //关闭流
         public void close() throws IOException
         {
             
               fr.close();
             
         }
        
              public int read(char[] cbuf, int off, int len)
              {
                     return read(cbuf, off,len) ;
                    
              }
             
             
             
             
         //关闭流
         public void myClose() throws IOException
         {
             
               fr.close();
             
         }
       
 
       
  }
 
 
  class MyBufferedReaderDemo
  {    
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              } 
            
      
               //主方法
                public static void main(String args[]) throws IOException
               {   
                   
                    FileReader fr =new FileReader("Demo.txt");
                   
                   
                    //创建自定义缓冲区
                    MyBufferedReader mf = new MyBufferedReader(fr);
                   
 
                    String str =null;
                    //按行读取
                    while ((str=mf.myReadLine())!=null)
                    {
 
                                 sop(str);
 
            
                    }
                   
            
                   
                    mf.myClose();
                   
                   
             
            
             
            
      
               }
             
      
  }    
 
            


 
 
          
     十九 IO流(MyIneNnmberReader)  -->重点

1 ) .  该节讲述了我的可获取行号还可读取行的类之间的包装类的设置以及继承类之间的关系

2 ) . Demo:


/*
 
 该节内容讲述了 :
 
  自定义可设置行号的缓冲区包装类,一种是通过原始的包装类方式;一种通过继承体系+包装类的方式
 
 
 讲述了 如何设置自己的 可获取行号 并可 打印行的 自定义包装类 ,详情见如下代码
 
 */
 
 
 
 
  import java.io.*;
 
 
  //自定义可设置行号的缓冲区包装类 -->原始包装类的方式-->下边有优化后的版本
/*   class MyLineNumerReader
  {
         private FileReader fr;
         private int lineNumber;
        
          
         MyLineNumerReader(FileReader fr)
         {
               this.fr=fr;
         }
        
        
         public void setLineNumber(int lineNumber)
         {
               this.lineNumber=lineNumber;
              
         }
        
           public int getLineNumber()
         {
             
               return lineNumber;
         }
        
       
        
         public String MyLineread() throws IOException
         {
               lineNumber++;
              
               StringBuilder sb =new StringBuilder();
              
               int ch=0;
              
               while((ch=fr.read())!=-1)
               {
                      if(ch=='\r')
                             continue;
                      if(ch=='\n')
                             return sb.toString();
                      else
                             sb.append((char)ch);
                     
                     
               }
               if(sb.length()!=0)
                      return sb.toString();
               return null;
         }
 
         public void myClose() throws IOException
         {
              
               fr.close();
         }
        
        
        
  } */
 
  //-------------------------------------------------------- 下边的是通过继承完善后的方式
 
 
  class MyBufferedReader extends Reader
  {
         private Reader fr;
      
         //将读流对象放入构造函数
         MyBufferedReader(Reader fr)
         {
            
               this.fr=fr;
            
         }
         //读一行
         public String myReadLine() throws       IOException
         {
               //数据存储地
               StringBuilder sb =new StringBuilder();//定义一个临时容器,因为最终要将数据变成字符串
            
               //数据量检测变量
               int ch =0 ;
            
               //读入
               while((ch=fr.read())!=-1)
               {
                   
                      if(ch=='\r')
                             continue;
                      if(ch=='\n')
                             return sb.toString();
                      else
                             sb.append((char)ch);
                   
                   
               }
               //这句是用来读取最后一行的
              if(sb.length()!=0)
                     return sb.toString();
            
               return null;
            
            
            
         }
            
              /*
            
                    覆盖reader类中的抽象方法
              */
                 //关闭流
         public void close() throws IOException
         {
            
               fr.close();
            
         }
       
              public int read(char[] cbuf, int off, int len)
              {
                     return read(cbuf, off,len) ;
                   
              }
            
            
            
            
         //关闭流
         public void myClose() throws IOException
         {
            
               fr.close();
            
         }
      
 
      
  }
 
 
 
 
 
 
   //自定义可设置行号的缓冲区包装类 -->继承体系+包装类的方式
  class MyLineNumerReader  extends MyBufferedReader
  {
             //用来记录行数
         private int lineNumber;
        
          
         MyLineNumerReader(Reader fr)
         {
             //父类当中已对reader实例化,因此这里传参即可
              super(fr);
         }
        
        
         public void setLineNumber(int lineNumber)
         {
               this.lineNumber=lineNumber;
              
         }
        
           public int getLineNumber()
         {
             
               return lineNumber;
         }
        
       
        
         public String MyLineread() throws IOException
         {
               //记录行数
               lineNumber++;
               //调取父类当中自定义的取行方法
              return super.myReadLine();
         }
 
        
        
  }
 
 
  class MyLineNumberReaderDemo
  {    
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              } 
            
      
               //主方法
                public static void main(String args[]) throws IOException
               {   
                  
            
                             FileReader fr =new FileReader("123.txt");  //用来读.java文件时 会出现 换行失败
                            
                             MyLineNumerReader mnr =new MyLineNumerReader(fr);
                            
                             String str=null;
                     
                           //设置行数
                            mnr.setLineNumber(20);
                     
                             while((str=mnr.MyLineread())!=null)
                           {
                                          //获取行数
                                 sop(mnr.getLineNumber()+"::"+str);
                                         
                                         
                           }
                                  
                           mnr.myClose(); 
            
      
               }
             
      
  }    
 
            


 

 
小结 :  

             1.  父类当中有的方法继承直接使用即可; 想要增强方法时,通过包装类的方式即可
        
      
          
     二十 IO流(字节流File读写操作)

1 ) . 该章讲述了 InputStream  读入 , OutputStream  写出 的相关操作  以及 available 用来获取文件字节数的方法

2 ) . 字节流与字符流在使用方式上的不同  :

2.1 字符流使用的是 字符数组 ; 字节流使用的是 字节数组

3 ) .  Demo : 


/*
 
 复写 : 字符流
 
 FileReader
 FileWriter
 
 BufferedReader
 BufferedWriter
 
 该节内容讲述了 :
 
 字节流:
 InputStream   读入
 OutputStream  写出
 
 需求 : 操作图片数据
 
 FileOutputStream  通过该方法写出数据
 
 FileInputStream  通过该方法读入数据
 
 读的三种方式 :
 
        [1] 第一种  按字节读一个存一个
       
        [2] 第二种 : 定义固定的外部容器, 读满.而后一次性存入指定地址
       [3] 第三种 : 定义弹性(容量可变)的外部容器,读完,而后一次性存入指定地址
       
       
 */
 
 
 
 
  import java.io.*;
  class FileStream
  {    
              public static void sop(Object obj)
              {
                     System.out.println(obj);
              } 
            
                    
                    
                     //读取数据方式三
                     public static void getRead_3() throws IOException
                     {                  
                           
                            FileInputStream fis =new FileInputStream("Demo.txt");
 
 
                    //     int num = fis.available();  该方法可用来获取文件的字节数
 
                           //该方法不建议用,因为弹性所以万一new的容量大了,就炸了,会导致内存溢出
                           byte[] cha =new byte[fis.available()];  // 通过available该方法可提前获取一个文件的字节数,也好定义一个刚刚好的数组
 
                            fis.read(cha);  //数组读到数组
                           
                            sop(new String(cha));  //将数组内的字节转化为字符串并输出
                           
                    
                     }
                    
                     //读取数据方式二
                     public static void getRead_2() throws IOException
                     {                  
                           
                            FileInputStream fis =new FileInputStream("Demo.txt");
 
 
                           byte[] cha =new byte[1024];
 
                           int len=0;
                           
                            while((len=fis.read(cha))!=-1)
                            {      //采用string构造方法中的取出范围
                                  sop(new String(cha,0,len));
                                 
                            }
                     }
                    
                    
                     //读取数据方式一
                     public static void getRead_1() throws IOException
                     {                  
                           
                            FileInputStream fis =new FileInputStream("Demo.txt");
 
                           
                            int len=0;
                           
                            while((len=fis.read())!=-1)
                            {
                                  sop((char)len);
                                 
                            }
                           
                            fis.close();
                     }
                    
      
               //主方法
                public static void main(String args[]) throws IOException
               {   
                  
                              //初始化一个字节流写出对象,并指定写出地址
                    /*     FileOutputStream fos = new FileOutputStream("Demo.txt");
                           
                           //将字符串转化为字符的格式写出到指定地址
                           fos.write("ABSDSF".getBytes());
                    
                           //关闭流资源
                           fos.close();   */
                    
                           getRead_3();
               }
             
      
  }    
 
            


 
 
小结 :  

             1.  请记得 读入 写出 ;
        
           2. IO流实现类的名字含义 :  开头单词是功能,后缀是它的父类 

           3. 字符串变数组 调用 getBytes()  ;  数组变字符串  toCharArray();

           4. 字符流的底层用的还是字节流的缓冲区,因此字符流内才会需要flush 刷新动作
          




  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值