zoukankan      html  css  js  c++  java
  • Java基础 IO流——第二部分

     

    新博客地址:Temi

    第一讲,IO流(BufferedWriter)

    一,字符流的缓冲区概述:

    1. 缓冲区的出现提高了对数据的读写效率。
    2. 对应类:BufferedWriter,BuuferedReader。(存在于java.io包中)
    3. 缓冲区要结合流才可以使用。       ====缓冲区是为了提高流的操作效率出现的,所以在创建缓冲区之前必须要现有流对象====
    4. 在流的基础上对流的功能进行了增强。

                          ========缓冲技术原理:BufferedWriter,BufferedReader对象里面封装了数组==========

    二,缓冲区操作类的简单了解:

                        BufferedWriter  类:

            1. 类的定义: public class BufferedWriter  extends Writer    将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
            2. 构造方法:public BufferedWriter (Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。===注:此处必须指明Writer对象作为参数,原因见概述第三条==========
            3. 构造方法:public BufferedWriter(Writer out, int sz)    创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
            4. 方法:public void newLine()  throws IOException     写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (' ') 符。
            5. public void write(int c)  throws IOException    写入单个字符。===注:此方法被重载多次,可写入char数组和字符串====

                       BufferedReader 类:

            1. 类的定义:public class BufferedReader  extends Reader    从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
            2. 构造方法:public BufferedReader(Reader in)     创建一个使用默认大小输入缓冲区的缓冲字符输入流。==注:指明Reader对象==
            3. 构造方法:public BufferedReader(Reader in,int sz)   创建一个使用指定大小输入缓冲区的缓冲字符输入流。
            4. 方法: public int read() throws IOException   读取单个字符。返回值:作为一个整数(其范围从 0 到 65535 (0x00-0xffff))读入的字符,如果已到达流末尾,则返回 -1
            5. 方法: public int read(char[] cbuf, int off,  int len)  throws IOException    将字符读入数组的某一部分。==注: 包括off下标==
            6. 方法: public String readLine() throws IOException     读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (' ')、回车 (' ') 或回车后直接跟着换行。
            7. 方法: public long skip(long n) throws IOException   跳过字符。返回值:实际跳过的字符数量。

    三,缓冲区写入操作步骤:

    1. 创建一个字符写入流对象:    FileWriter fw=new FileWriter("buf.txt");
    2. 创建缓冲区对象:         BufferedWriter bw=new BufferedWriter(fw);
    3. 调用缓冲区对象方法写入数据:         bw.write("abcd");   ===注:此步骤执行后,文件若不存在会被创建,但是,数据并没有写入文件。=====
    4. 刷新缓冲区:                          bw.flush();                 ===注:用到缓冲区后一定要刷新===
    5. 关闭缓冲区:                          bw.close();                  ===注:缓冲区只是提高操作效率,真正实现写操作的是FileWriter对象,所以缓冲区的关闭其实是关闭的是他所提高效率的流对象,即FileWriter 对象。===

    四,代码练习:

     1 /*
     2 * 缓冲区对象使用联系。重点观察写入过程
     3 *什么时候创建文件,以及将数据写入文件的时机
     4 */
     5 import java.io.*;
     6 import java.util.Scanner;
     7 
     8 
     9 public class BufferedWriterDemo {
    10              public static void main(String args[]){
    11                  
    12                    //声明实际写文件对象引用
    13                    FileWriter fw=null;
    14                    
    15                    //声明缓冲区对象引用
    16                    BufferedWriter bw=null;
    17                    
    18                    //表示文件字符串
    19                    String fileName="E:/buf.txt";
    20                    
    21                    //异常处理
    22                    try{
    23                        
    24                        //实例化对象引用
    25                        fw=new FileWriter(fileName);
    26                        
    27                        bw=new BufferedWriter(fw);
    28                        
    29                        
    30                        //调用缓冲对象方法写入数据此时并没有写进文件中,但是文件已经创建。若文件存在由于不是追加写方式,源文件内容清空
    31                        bw.write("abcd");
    32                        
    33                        //写入文件换行符,此方法跨平台
    34                        bw.newLine();
    35                        
    36                        //写入第二行
    37                        bw.write("第二行");
    38                        
    39                        //此处停顿,按任意键继续,此时可观察文件变化
    40                        System.out.println("刷新流之前:");
    41                        System.out.println("按任意键继续:");
    42                        
    43                        
    44                        //用户输入任意字符后继续;
    45                        new Scanner(System.in).next();
    46                        
    47                        //刷新缓冲流,将字符写入文件。
    48                        bw.flush();
    49                        
    50                        //此后观察文件发现数据已经写入
    51                        System.out.println("刷新流之后:");
    52                        
    53                         
    54                    }catch(IOException e){
    55                         System.out.println("写入操作发生错误!");
    56                    }finally{
    57                        try{
    58                            if(bw!=null)
    59                                bw.close();
    60                        }catch(IOException e){
    61                            System.out.println("关闭文件发生错误!");
    62                        }
    63                      
    64                            
    65                    }
    66              }
    67 }

    第二讲:IO流(BufferedReader)

     一,BufferedReader类的了解:见第一讲

    二,缓冲区读入步骤:

    1. 创建一个读取流对象和文件相关联。     FileReader fr=new FileReader("buf.txt");
    2. 创建缓冲读取对象,提高读取操作效率。BufferedReader br=new BufferedReader(fr);
    3. 使用缓冲区对象方法读取数据:            br.readLine();   ==注:readLine() 方法对于读取文本文件特别方便。特别注意:如果已到达流末尾,则返回 null 而不是 -1 ,此方法返回的字符串中不包括换行符==
    4. 关闭缓冲区。

    三,代码练习:

     1 import java.io.*;
     2 
     3 
     4 public class BufferedReaderDemo {
     5 
     6     public static void main(String[] args) {
     7         // TODO Auto-generated method stub
     8            
     9            //创建对象引用
    10            FileReader fr=null;
    11            BufferedReader br=null;
    12            
    13            //文件字符串
    14            String fileName="E:/buf.txt";
    15            
    16            
    17            //异常处理
    18            try{
    19                fr=new FileReader(fileName);
    20                
    21                br=new BufferedReader(fr);
    22                
    23                //创建字符串,保存读取内容
    24                String readLine=null;
    25                
    26                //循环读取文件内容,注意此处的判断条件是 null  而不是   -1
    27                while((readLine=br.readLine())!=null){
    28                    System.out.println(readLine);
    29                }
    30                
    31                
    32                //处理异常,给出提示
    33            }catch(FileNotFoundException e){
    34                System.out.println("文件没有找到!"+e.toString());
    35            }catch(IOException e){
    36                System.out.println("文件读取发生错误"+e.toString());
    37            }finally{
    38                try{
    39                    if(br!=null)
    40                        br.close();
    41                }catch(IOException e){
    42                    System.out.println("文件关闭失败:"+e.toString());
    43                }
    44            }
    45     }
    46 
    47 }

    第三讲:IO流(通过缓冲区复制文本文件)

    一,练习:通过缓冲区复制一个 .java文件

                 注意事项:

        1. readLine() 方法返回的字符串中不包括换行符,所以再写入新的文件时应该加上,使用BudderedWriter.newLine()方法。
        2. 每次循环写入都必须刷新

    二,代码练习:

     1 import java.io.*;
     2 
     3 
     4 public class CopyFile {
     5              public static void main(String args[]){
     6                      
     7                      //创建对象引用
     8                      BufferedReader br=null;
     9                      
    10                      BufferedWriter bw=null;
    11                      
    12 
    13                     //源文件字符串表示
    14                      String srcFileName="E:/test.java";
    15                      
    16 
    17                      //目标文件字符串表示
    18                      String destFileName="E:/dest.java";
    19   
    20                      //判断是否是.java文件
    21                      if(!srcFileName.endsWith(".java")){
    22                          System.out.println("文件后缀名不是 .java");
    23                          
    24                          //如果不是.java文件返回
    25                          return;
    26                      }
    27                      
    28 
    29 
    30                      //异常处理
    31                      try{
    32 
    33 
    34                          //使用匿名对象实例化缓冲区对象br 
    35                          br=new BufferedReader(new FileReader(srcFileName));
    36                          
    37                          bw=new BufferedWriter(new FileWriter(destFileName));
    38                          
    39                          //接受读入的字符串
    40                          String readLine=null;
    41                          
    42 
    43                          //循环读取
    44                          while((readLine=br.readLine())!=null){
    45 
    46                                  //读取一行,写入一行
    47                              bw.write(readLine);
    48 
    49                                  //由于readLine() 方法没有返回换行符,此处应当换行
    50                              bw.newLine();
    51 
    52                                  //刷新缓冲区,将数据写入文件
    53                              bw.flush();
    54                          }
    55 
    56                          //成功提示
    57                          System.out.println("文件拷贝完毕!");
    58 
    59                       //异常处理以及提示
    60                      }catch(FileNotFoundException e){
    61                          System.out.println("源文件没有找到,或者目标文件不存在"+e.toString());
    62                      }catch(IOException e){
    63                          System.out.println("文件拷贝失败"+e.toString());
    64                      }
    65              }
    66 }

     第四讲:IO流(readLine的原理图例)

    原理概括,readLine 方法最终操作其实也是一个一个的读取数据,只不过它把读取到的数据存进了自己的缓冲区中,当遇到换行符时,结束读取,并一次性返回所有数据。如图:

     

    第五讲:IO流(MyBufferedReader)

     自定义readLine方法代码:

      1 import java.io.*;
      2 
      3 class MyBufferedReader {
      4 
      5           //定义对象引用,并进行封装,使用构造函数实例化
      6       private FileReader reader;
      7       
      8 
      9          //定义缓冲区,缓冲读入的字符
     10       private char[] str;
     11       
     12      
     13           //构造方法,传入一个FileReader对象进行文件读操作,使用默认缓冲区
     14       public MyBufferedReader(FileReader reader){
     15           this.reader=reader;
     16           this.str=new char[1024];
     17       }
     18       
     19 
     20          //使用自定义的缓冲区大小
     21       public MyBufferedReader(Reader Filereader,int size){
     22           this.reader=reader;
     23           this.str=new char[size];
     24       }
     25       
     26       
     27 
     28           //自定义函数进行缓冲的高效读写。此处异常交由调用者处理。
     29       public String myReadLine() throws IOException{
     30                     
     31                      //保存读取的单个字符;
     32              int ch=0;
     33                      
     34                      //记录读取的总字符数量
     35              int num=0;
     36 
     37                      //循环读取内容
     38              while((ch=this.reader.read()) != -1){
     39                    
     40 
     41                            //如果字符为 '
    ' 则跳过继续下一轮循环
     42                    if(ch == '
    ')
     43                        continue;
     44 
     45                            //如果字符为 '
    ' 则结束循环,返回读取的内容
     46                    else if(ch == '
    ')
     47                        return new String(str,0,num);
     48 
     49                           //如果超出缓冲区大小,则结束循环,返回读取内容
     50                           else if(num>=size)
     51                        return new String(str,0,num);
     52                    else{
     53 
     54                                    //将读取的字符保存在字符数组中,下标加一
     55                        str[num]=(char)ch;
     56                        num++;
     57                    }
     58              }
     59 
     60                      //判断最后一行数据是否存在
     61              if(num!=0)
     62              return new String(str,0,num);
     63              else return null;
     64       }
     65       
     66       
     67           //关闭流,实为关闭内部流对象。此处异常抛出。
     68       public void myClose() throws IOException{
     69           this.reader.close();
     70       }
     71 }
     72 
     73 
     74 
     75 public class MyBufferedReaderDemo {
     76 
     77     public static void main(String[] args) {
     78         // TODO Auto-generated method stub
     79         MyBufferedReader mbr=null;
     80         
     81         String fileName="E:/testmybuf.txt";
     82         
     83         try{
     84             mbr=new MyBufferedReader(new FileReader(fileName));
     85             
     86             String readLine;
     87 
     88                //循环读取
     89             while((readLine=mbr.myReadLine())!=null){
     90                 System.out.println(readLine);
     91             }
     92             System.out.println("读取完毕!");
     93             
     94         }catch(IOException e){
     95             System.out.println("读取文件错误"+e.toString());
     96         }finally{
     97             try{
     98                 if(mbr!=null){
     99                     mbr.myClose();
    100                 }
    101             }catch(IOException e){
    102                 System.out.println("文件关闭时发生错误!"+e.toString());
    103             }
    104         }
    105     }
    106 
    107 }

    第六讲、第七讲、第八讲:装饰设计模式、装饰和继承的区别、自定义装饰类

    一,装饰设计模式简介:

      1.  装饰模式(Decorator)的定义:当想对已有对象进行功能增强时,可定义一个类,这个类将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类称之为装饰类。又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
      2. 装饰模式的特点:
          1. 装饰类通常都会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
          2. 装饰对象包含一个真实对象的引用(reference).
          3. 通常装饰类,与被装饰类实现同一个接口。即属于同一个接口或者类。
      1. 装饰设计模式和继承的区别:
          1. 装饰模式比继承要灵活。避免了继承体系的臃肿,且降低了类与类之间的关系。装饰模式扩展的是对象的功能,不需要增加类的数量,而类继承扩展是类的功能,在继承的关系中,如果我们想增加一个对象的功能,我们只能通过继承关系,在子类中增加两个方法。
          2. 装饰模式是一种动态行为,可以对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成什么样的,该类的对象便具有什么样的功能,无法动态的改变。

     

     

    二,代码练习(第五讲代码增强):

     

      1 import java.io.*;
      2 
      3 class MyBufferedReader {
      4 
      5           //定义对象引用,并进行封装,使用构造函数实例化
      6       private FileReader reader;
      7       
      8 
      9          //定义缓冲区,缓冲读入的字符
     10       private char[] str;
     11       
     12      
     13           //构造方法,传入一个FileReader对象进行文件读操作,使用默认缓冲区
     14       public MyBufferedReader(FileReader reader){
     15           this.reader=reader;
     16           this.str=new char[1024];
     17       }
     18       
     19 
     20          //使用自定义的缓冲区大小
     21       public MyBufferedReader(Reader Filereader,int size){
     22           this.reader=reader;
     23           this.str=new char[size];
     24       }
     25       
     26       
     27 
     28           //自定义函数进行缓冲的高效读写。此处异常交由调用者处理。
     29       public String myReadLine() throws IOException{
     30                     
     31                      //保存读取的单个字符;
     32              int ch=0;
     33                      
     34                      //记录读取的总字符数量
     35              int num=0;
     36 
     37                      //循环读取内容
     38              while((ch=this.reader.read()) != -1){
     39                    
     40 
     41                            //如果字符为 '
    ' 则跳过继续下一轮循环
     42                    if(ch == '
    ')
     43                        continue;
     44 
     45                            //如果字符为 '
    ' 则结束循环,返回读取的内容
     46                    else if(ch == '
    ')
     47                        return new String(str,0,num);
     48 
     49                           //如果超出缓冲区大小,则结束循环,返回读取内容
     50                           else if(num>=size)
     51                        return new String(str,0,num);
     52                    else{
     53 
     54                                    //将读取的字符保存在字符数组中,下标加一
     55                        str[num]=(char)ch;
     56                        num++;
     57                    }
     58              }
     59 
     60                      //判断最后一行数据是否存在
     61              if(num!=0)
     62              return new String(str,0,num);
     63              else return null;
     64       }
     65       
     66       
     67           //关闭流,实为关闭内部流对象。此处异常抛出。
     68       public void myClose() throws IOException{
     69           this.reader.close();
     70       }
     71 
     72 
     73 
     74        //覆写父类中的抽象方法
     75         @Override
     76     public int read(char[] cbuf, int off, int len) throws IOException {
     77 
     78                 //调用真是实现类实现具体操作
     79         return this.reader.read(cbuf, off, len);
     80     }
     81 
     82 
     83          //覆写父类中的抽象方法
     84     @Override
     85     public void close() throws IOException {
     86         this.reader.close();
     87         
     88     }
     89 }
     90 
     91 
     92 
     93 public class MyBufferedReaderDemo {
     94 
     95     public static void main(String[] args) {
     96         // TODO Auto-generated method stub
     97         MyBufferedReader mbr=null;
     98         
     99         String fileName="E:/testmybuf.txt";
    100         
    101         try{
    102             mbr=new MyBufferedReader(new FileReader(fileName));
    103             
    104             String readLine;
    105 
    106                //循环读取
    107             while((readLine=mbr.myReadLine())!=null){
    108                 System.out.println(readLine);
    109             }
    110             System.out.println("读取完毕!");
    111             
    112         }catch(IOException e){
    113             System.out.println("读取文件错误"+e.toString());
    114         }finally{
    115             try{
    116                 if(mbr!=null){
    117                     mbr.myClose();
    118                 }
    119             }catch(IOException e){
    120                 System.out.println("文件关闭时发生错误!"+e.toString());
    121             }
    122         }
    123     }
    124 
    125 }

    第九讲、第十讲:IO流(LineNumberReader)、IO流(MyineNumberReader)

    一,LineNumberReader类的了解:

        1. 类的定义:public class LineNumberReader  extends BufferedReader     跟踪行号的缓冲字符输入流。此类定义了方法 setLineNumber(int)
          getLineNumber(),它们可分别用于设置和获取当前行号。==注:默认情况下,行编号从 0 开始。该行号随数据读取在每个行结束符处递增,可以通过调用 setLineNumber(int) 更改行号。setLineNumber(int) 不会实际更改流中的当前位置;它只更改将由 getLineNumber() 返回的值。===
        2. 方法:public int getLineNumber()     获得当前行号。
        3. 方法:public void setLineNumber(int lineNumber)    设置当前行号。

    二,LineNumberReader类的原理:

                             在类的内部增加了一个行号计数器。

    三,代码练习:

     1 import java.io.*;
     2 class  LineNumberReaderDemo
     3 {
     4     public static void main(String[] args) 
     5     {
     6         LineNumberReader lnr=null;
     7         try
     8         {
     9              
    10             lnr=new LineNumberReader(new FileReader("LineNumberReaderDemo.java"));
    11 
    12                         //设置行号:此设置仅对 getLineNumber() 有效并不会影响源文件
    13             lnr.setLineNumber(100); 
    14 
    15                         //接受读取的字符串
    16             String line=null;
    17 
    18                         //循环读取
    19             while ((line=lnr.readLine())!=null ){
    20                                 
    21                                 //输出行号与内容
    22                 System.out.println(lnr.getLineNumber()+":"+line); 
    23             }
    24         }
    25 
    26                 //异常处理
    27         catch (IOException e)
    28         {
    29             throw new RuntimeException("读取数据失败");
    30         }
    31         finally
    32         {
    33             try
    34             {
    35                 if(lnr!=null)
    36                     lnr.close();
    37             }
    38             catch (IOException e)
    39             {
    40                 throw new RuntimeException("读取流关闭失败");
    41             }
    42         }    
    43     }
    44 }

    第十一讲,十二讲:IO流(字节流File读写操作)、IO流(拷贝图片)

    一,字节流概述:

      1. 字节流除了可以操作文本文件外还可以操作其他文件,例如媒体文件。
      2. 字节流的顶层类: InputStream,OutputStream。
      3. 字节流的写入是直接写入文件的,所以不用进行刷新。==注:因为字节流操作的是字节,即数据的最小单位,不需要像字符流一样要进行转换为字节。所以可直接将字节数据写入到指定文件中。==

    二,InputStream类的了解:

        1. 构造方法:public abstract class InputStream  extends Object  implements Closeable   此抽象类是表示字节输入流的所有类的超类。
        2. 独特的方法:public int available() throws IOException   返回可以不受阻塞地从此输入流读取(或跳过)的估计字节数;如果到达输入流末尾,则返回 0。===注:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。===
        3. 直接已知子类:AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream

    三,拷贝图片步骤:

        1. 用字节读取流对象和图片关联。
        2. 用字节流对象创建一个图片文件,存储获取到的图片数据。
        3. 通过循环读写,完成数据的存储。===注:此处不存在流的刷新====
        4. 关闭资源。

    四,代码练习,拷贝图片:

            

     1 import java.io.*;
     2 public class  CopyImage{
     3     public static void main(String[] args){
     4 
     5                 //创建对象引用
     6         FileInputStream fis=null;
     7         FileOutputStream fos=null;
     8 
     9 
    10         try{
    11             //实例化对象,与文件相关联
    12             fis=new FileInputStream("E:/image/pub.jpg");
    13              
    14             fos=new FileOutputStream("E:/image/pub2.jpg");
    15 
    16 
    17             //创建数组用于保存读取到的数据                                                           byte[] b=new byte[1024];
    18 
    19                         //记录读取到的字节数
    20             int len=0;
    21 
    22                         
    23                         //循环读取
    24             while ((len=fis.read(b))!=-1){
    25                                 
    26                                 //边读边写实现复制
    27                 fos.write(b,0,len);
    28             }
    29         }
    30 
    31 
    32         catch (IOException e)
    33         {
    34             throw new RuntimeException("图片复制失败");
    35         }
    36         finally
    37         {
    38             try
    39             {
    40                 if(fis!=null)
    41                     fis.close();//关闭输入字节流
    42             }
    43             catch (IOException e)
    44             {
    45                 throw new RuntimeException("读取字节流关闭失败");
    46             }
    47             try
    48             {
    49                 if(fos!=null)
    50                     fos.close();//关闭输出字节流
    51             }
    52             catch (IOException e)
    53             {
    54                 throw new RuntimeException("写入字节流关闭失败");
    55             }
    56         }
    57     }    
    58 }

    第一十三讲、一十四讲:IO流(字节流的缓冲区)、IO流(自定义字节流的缓冲区-read和write的特点)

     一,缓冲输出流的了解:

        1. 用到的类BufferedOutputStream,BufferedInputStream.
        2. BufferedInputStream类的定义:public class BufferedInputStreamextends FilterInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 markreset 方法的能力。
        3. 方法与InputStream类相同。

    二,缓冲区的原理:将数据拷贝一部分,读取一部分,循环,直到数据全部读取完毕。如图:

    三,字节流操作注意事项:

        1. 读取方法应当返回 int 类型,而不是 byte 类型。==原理:数据在内存中以二进制形式存在,当读到八个一时,转换为 byte类型是 -1 ,则此时使用 -1作为文件结束的判断逻辑将会出错。解决办法:将byte 类型转换为 int 类型,并将转后的的数据的前24位二进制用零填充。代码实现: return byte&0xff;     0xff即 255 二进制形式为 00000000  000000000  00000000  11111111   所以将byte的前24位变为零==

    四,代码练习:

      1 import java.io.*;
      2 
      3 
      4 public class MyBufferedInputStream {
      5              
      6     
      7              //定义被包装的类成员
      8              private InputStream in;
      9              
     10              //定义缓冲区的大小 
     11              private int size=1024;
     12              
     13              
     14              //定义变量分别表示读取数量,以及当前数组下标
     15              private int pos=0,count=0;
     16              
     17              //声明已知长度的缓冲区
     18              byte[] buf=new byte[size];
     19              
     20              
     21              //定义构造方法
     22              public MyBufferedInputStream(InputStream in){
     23                  this.in=in;
     24              }
     25              
     26             
     27              //定义构造方法
     28              public MyBufferedInputStream(InputStream in,int size){
     29                  this.in=in;
     30                  this.size=size;
     31              }
     32              
     33              
     34              //声明对外提供的方法
     35              //功能:一次从缓冲区中读取一个字节数据。
     36              public int myRead() throws IOException{
     37                  
     38                  //缓冲区中没有数据
     39                   if(count==0){
     40                       
     41                       //将数据读入缓冲区
     42                       count=in.read(buf);
     43                       
     44                       //到达文件末尾返回 -1
     45                       if(count<=0){
     46                           return -1;
     47                       }
     48                       
     49                       //返回缓冲区中的第一个字节
     50                       byte read=buf[pos];
     51                       
     52                       //缓冲区数据量 减一
     53                       count--;
     54                       
     55                       //缓冲区下标加一
     56                       pos++;
     57                       
     58                       //返回整形数据,原数据与上255,将钱24位设定为零,避免读取的字节为八个一时,错误判断为文件结束
     59                       return read&0xff;
     60                       
     61                   }
     62                   else {
     63                       
     64                       //缓冲区中有数据,直接返回
     65                       byte read=buf[pos];
     66                       
     67                       //改变下标
     68                       count--;
     69                       pos++;
     70                       
     71                       //返回修改之后的值
     72                       return read&0xff;
     73                   }
     74              }
     75              
     76              
     77              //定义主方法拷贝mp3
     78              public static void main(String args[]){
     79                  
     80                  
     81                  //声明引用句柄
     82                     FileInputStream src=null;
     83                     FileOutputStream dest=null;
     84                     MyBufferedInputStream mbi=null;
     85                     
     86                     //异常处理
     87                     try{
     88                         
     89                         //实例化源文件,目标文件
     90                         src=new FileInputStream("E:/my.mp3");
     91                         dest=new FileOutputStream("E:/my2.mp3");
     92                         
     93                         //实例化缓冲区读取对象
     94                         mbi=new MyBufferedInputStream(src);
     95                         
     96                         
     97                         //接受读取的数据
     98                         int read=0;
     99                         
    100                         //循环读取数据并写入文件
    101                         while((read=mbi.myRead())!=-1){
    102                             dest.write(read);
    103                         }
    104                         
    105                         
    106                         //异常处理
    107                     }catch(IOException e){
    108                         System.out.println("文件复制错误"+e.toString());
    109                     }finally{
    110                         try{
    111                             if(src!=null){
    112                                 src.close();
    113                             }
    114                             if(dest!=null){
    115                                 dest.close();
    116                             }
    117                         }catch(IOException e){
    118                             System.out.println("文件关闭发生错误"+e.toString());
    119                         }
    120                     }
    121              }
    122 }

     

     

    第一十五讲:IO流(读取键盘录入)

    一,使用到的对象:System.in

        1. 该对象的定义:public static final InputStream in   “标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。======注:次对象使用完毕后可以不进行显示的关闭==========
        2. System的另一个静态对象:  public static final PrintStream out    “标准”输出流。此流已打开并准备接受输出数据。

    二,需求分析:

                       通过键盘录入数据,当录入一行数据后,就将改行打印,如果录入的数据是 end ,那么停止录入。

    三,代码实现:

     1 import java.io.*;
     2 
     3 
     4 public class ReadIn {
     5 
     6     public static void main(String[] args)  {
     7         // TODO Auto-generated method stub
     8         
     9         //创建输入对象,指向System.in  ======次对象可以不用显示关闭==========
    10         InputStream in=System.in;
    11         
    12         //缓冲读入的字符
    13         StringBuilder sb=new StringBuilder();
    14         
    15         
    16         //一直读取键盘输入,直到用户输入end字符串
    17         while(true){
    18             
    19             //接受输入字符
    20             int ch=0;
    21             
    22             
    23             //读取输入内容
    24              try {
    25                   ch=in.read();
    26             } catch (IOException e) {
    27                  System.out.println("读取发生错误"+e.toString());
    28             }
    29              
    30              //进行判断,如果是  '
    ' 则进行下一次读取
    31              if(ch==13)
    32                  continue;
    33              
    34              //如果是 '
    ' 字符结束读取,打印用户的输入
    35              else if(ch==10){
    36                  
    37                  //如果用户输入的是  "end" 字符串,则结束读取
    38                  if("end".equals(sb.toString()))
    39                      break;
    40                  
    41                  //否则打印用户输入,进行下一次读取
    42                  System.out.println(sb);
    43                  
    44                  //打印完毕必须清空缓冲区
    45                  sb.delete(0, sb.length());
    46              }else 
    47                  
    48                  //普通字符存入缓冲区中
    49              sb.append((char)ch);
    50              
    51         }
    52     }
    53 
    54 }

                   ===========键盘录入也可以使用 crtl + c 快捷键结束===============

    第一十六讲,一十七讲:IO流(读取转换流),IO流(写入转换流)

    一,需求分析:

                      使用readLine()方法读取键盘的一行数据。

                      使用newLine() 方法进行换行。

    二,思路分析:

      1. readLine() 方法是字符流BufferedReader类中的方法。
      2. 负责接收键盘录入的read() 方法是字节流InputStream 类中的方法。
      3. newLine() 方法是字符流BufferedWriter 类中的方法。

    三,解决办法:

      1. 使用转换流。InputStreamReader(字节转换字符流),OutputStreamReader(字符流转换字节流)。
        1. InputStreamReader 类的定义:public class InputStreamReaderextends Reader
        2. InputStreamReader 类的构造方法:
          1. public InputStreamReader(InputStream in)    创建一个使用默认字符集的 InputStreamReader。
          2. public InputStreamReader(InputStream in, String charsetName) throws UnsupportedEncodingException  创建使用指定字符集的 InputStreamReader。
          3. public InputStreamReader(InputStream in, Charset cs)     创建使用给定字符集的 InputStreamReader。
        3. OutputStreamWriter 类的定义:public class OutputStreamWriterextends Writer   OutputStreamWriter 是字符流通向字节流的桥梁
        4. OutputStreamWriter 类的构造方法:
          1. public OutputStreamWriter(OutputStream out)     创建使用默认字符编码的 OutputStreamWriter。
          2. public OutputStreamWriter(OutputStream out,  Charset cs)      创建使用给定字符集的 OutputStreamWriter。
          3. public OutputStreamWriter(OutputStream out,  CharsetEncoder enc)     创建使用给定字符集编码器的 OutputStreamWriter。
      2. 将字节流转换成字符流,之后再使用字符流的 readLine() ,newLine()方法进行数据的按行读取,以及进行换行操作。

    四,练习代码:

     

     1 import java.io.*;
     2 
     3 
     4 public class TransStreamDemo {
     5              public static void main(String args[]){
     6                  
     7                  //创建字符流对象,此对象包装了字节流对象
     8                  InputStreamReader isr=new InputStreamReader(System.in);
     9                  
    10                  
    11                  //创建缓冲字符流对象,使用readLine() 方法
    12                  BufferedReader br=new BufferedReader(isr);
    13                  
    14                  //接受输入的字符串
    15                  String line=null;
    16                  
    17                  //循环读取用户输入内容
    18                  while(true){
    19                      try {
    20                          
    21                          //如果用户输入 "end" 则结束读取
    22                         if("end".equals(line=br.readLine()))
    23                              break;
    24                     } catch (IOException e) {
    25                         // TODO Auto-generated catch block
    26                         System.out.println("读取发生错误"+e.toString());
    27                     }
    28                      
    29                      //输出用户的输入
    30                      System.out.println(line);
    31                  }
    32                  
    33              }
    34 }

     ===============键盘录入最常见写法:BufferedReaderin=new BufferedReader(new InputStreamReader(System.in));====================

    第一十八讲:IO流(流操作规律-1)

     一,操作流程:

      1. 明确目的和源:
        1. 源:键盘录入。
        2. 目的:控制台(屏幕设备)。
      2. 需求分析:
        1. 把键盘录入的数据存储到一个文件中。======源:键盘,目的地:文件(硬盘)==========
        2. 把一个文件数据打印到控制台上。      ======源:文件,目的地:控制台==========
      3. 通过两个明确来选择众多流对象中具体应该用那中体系。--------1,明确目的和源。2,操作的文件或者是源,是否是文本形式的。-----------------
      4. 当体系明确后再明确具体使用那个对象。        ====源设备:内存,硬盘,键盘,目的:内存,硬盘,控制台=====

    二,练习分析:

      1. 将一个文本文件数据,存储到另一个文本文件中,即复制文件。
        1. 源:应为是源所以使用读取流(InputStream, Reader)。
        2. 是不是文本文件  (Reader)。  ===明确体系===
        3. 确定源对象:因为设备是硬盘文件,选择FileReader。      FileReader  fr=new FileReader("源.txt");
        4. 目的:因为是目的所以使用写入流(OutpurStream, Writer)。
        5. 是不是文本文件  (Writer)。   
        6. 确定目的对象:FileWriter。                                       FileWriter fw=new FileWriter("目的.txt");
        7. 输入流提高效率:  加入BufferedReader                       BufferedReader br=new BufferedReader(fr);
        8. 输出流提高效率:  加入BufferedWriter                        BufferedWriter bw=new BufferedWriter(fw);

    三,复制图片代码练习:

     

     1 import java.io.*;
     2 
     3 
     4 public class MyImage {
     5              public static void main(String args[]){
     6                   
     7                  //确定使用的对象===源:硬盘,图片文件,目的:硬盘,图片文件
     8                  FileInputStream fis=null;
     9                  FileOutputStream fos=null;
    10                  
    11                  
    12                  //使用缓冲流提高效率
    13                  BufferedInputStream bis=null;
    14                  BufferedOutputStream bos=null;
    15                  
    16                  
    17                  String src="F:/Image/psb.jpg";
    18                  String dest="F:/Image/psb2.jpg";
    19                  
    20                  try{
    21                      
    22                      //实例化对象
    23                       fis=new FileInputStream(src);
    24                       bis=new BufferedInputStream(fis);
    25                       
    26                       bos=new BufferedOutputStream(fos=new FileOutputStream(dest));
    27                       
    28                       //转存读入的内容
    29                       byte[] b=new byte[1024];
    30                       
    31                       //循环读取写入实现文件复制
    32                       while(bis.read(b)!=-1)
    33                           bos.write(b);
    34                       
    35                       //给出成功提示
    36                       System.out.println("文件复制成功");
    37                  }catch(IOException e){
    38                      System.out.println("文件复制错误!"+e.toString());
    39                  }finally{
    40                      try{
    41                          if(bis!=null)
    42                              bis.close();
    43                          if(bos!=null)
    44                              bos.close();
    45                      }catch(IOException e){
    46                          System.out.println("文件关闭过程发生错误!"+e.toString());
    47                      }
    48                  }
    49              }
    50 }

    第一十九讲:IO流(流操作规律-2)

    一,扩展:把录入的数据按照指定的编码表(UTF-8)(默认编码表是GBK),将数据存到文件中。

      1. 想要实现使用指定的编码表将数据存入文件中,只能使用转换流。OutputStreamWriter osw=new OutputStreamWriter(new FileInputStream("d.txt"),"UTF-8");
      2. 提高效率:BufferedWriter bw=new BufferedWriter(osw);

    ====转换流的使用时机:1,字符和字节之间的桥梁。2,涉及到字符编码转换。===

    二,代码练习:使用指定的编码表(UTF-8)将键盘输入的数据存入文件中

     

     1 import java.io.*;
     2 
     3 public class TransStreamDemo2 {
     4              public static void main(String args[]){
     5                  
     6                  
     7                  //确定输入源为键盘,创建相对应的输入流对象,并使用装饰流提高效率
     8                  InputStream in=System.in;
     9                  
    10                  //输入流输入的为文本文件,使用转换流进行转换
    11                  InputStreamReader isr=new InputStreamReader(in);
    12                  BufferedReader br=new BufferedReader(isr);
    13                  
    14                  //读取键盘输入的常用格式:
    15                  //以上三句话可以省略写为:BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
    16                  //确定输出源为文件,创建相对应输出流对象,并使用装饰流提高效率
    17                  FileOutputStream fos=null;
    18                  
    19                  //输出流输出的为文本文件,使用输出流进行转换
    20                  OutputStreamWriter isw=null;
    21                  BufferedWriter bw=null;
    22                  try{
    23                      
    24                      //创建输出缓冲流,其中转换里流明确使用UTF-8编码格式
    25                      bw=new BufferedWriter(isw=new OutputStreamWriter(fos=new FileOutputStream("E:/test.txt"),"UTF-8"));
    26                      
    27                      //接受读入的一行数据
    28                      String line=null;
    29                      
    30                      //循环读取写入
    31                      while(!"end".equals(line=br.readLine())){
    32                          
    33                          //写入文件
    34                          bw.write(line);
    35                          
    36                          //写入换行符
    37                          bw.newLine();
    38                          
    39                          //缓冲流需要刷新
    40                          bw.flush();
    41                      }
    42                      
    43                      //成功提示
    44                      System.out.println("存入完毕");
    45                      
    46                      //异常处理
    47                  }catch(IOException e){
    48                      System.out.println("发生错误!"+e.toString());
    49                  }finally{
    50                      try{
    51                          if(bw!=null)
    52                              bw.close();
    53                      }catch(IOException e){
    54                          System.out.println("文件关闭发生错误!"+e.toString());
    55                      }
    56                  }
    57              }
    58 }

     

    第二十讲:IO流(改变标准输入输出设备)

    一,改变标准输入、输出设备用到的System类中的方法:

        1. public static void setIn (InputStream in)  重新分配“标准”输入流。
        2. public static void setOut(PrintStream out)   重新分配“标准”输出流。

    二,代码练习:通过改变标准输入、输出实现文件的复制

     1 import java.io.*;
     2 
     3 
     4 public class TransStreamDemo3 {
     5              public static void main(String args[]){
     6                  
     7                  //目的和源都是 文件,创建相对应的流对象引用
     8                  FileInputStream in=null;
     9                  PrintStream out=null;
    10                  
    11                  //确定操作的是文本文件,使用相对应的缓冲刘提高效率
    12                  BufferedWriter bw=null;
    13                  BufferedReader br=null;
    14                  
    15                  //异常处理
    16                  try{
    17                      
    18                      //实例化输入输出流对象
    19                      in=new FileInputStream("E:/test.txt");
    20                      out=new PrintStream("E:/test_copy.txt");
    21                      
    22                      //分别调用 setIn() setOut() 方法重定向标准输入、输出。
    23                      System.setIn(in);
    24                      System.setOut(out);
    25                      
    26                      
    27                      //实例化缓冲流。使用转换流进行转换
    28                      br=new BufferedReader(new InputStreamReader(System.in));
    29                      bw=new BufferedWriter(new OutputStreamWriter(System.out));
    30                      
    31                      //接受读入的一行数据
    32                      String line=null;
    33                      
    34                      //循环读入写入操作
    35                      while((line=br.readLine())!=null){
    36                          
    37                          //写入数据
    38                          bw.write(line);
    39                          
    40                          //换行操作
    41                          bw.newLine();
    42                          
    43                          //清空缓冲区
    44                          bw.flush();
    45                      }
    46                      
    47                      //操作成功给出提示
    48                      System.out.println("文件复制成功!");
    49                  }catch(FileNotFoundException e){
    50                      System.out.println("文件没有找到"+e.toString());
    51                  }catch(IOException e){
    52                      System.out.println("文件复制发生作物"+e.toString());
    53                  }finally{
    54                      try{
    55                          if(br!=null)
    56                              br.close();
    57                          if(bw!=null)
    58                              bw.close();
    59                      }catch(IOException e){
    60                          System.out.println("文件关闭发生错误"+e.toString());
    61                      }
    62                  }
    63              }
    64 }

     

    第二十一讲,二十二讲:IO流(异常的日志信息),IO流(系统信息)

    一,需求分析:

      1. 将程序运行时异常记录在文件中。
      2. 加入异常产生的时间。

    二,思路:

      1. 获取文件输出流,输出异常信息。
      2. 记录异常产生时间,并输入文件。
      3. 获取异常信息,并将之输入文件。

    三,代码实现:

     1 import java.io.*;
     2 import java.util.Date;
     3 import java.text.SimpleDateFormat;
     4 
     5 
     6 public class ExceptionInfo {
     7              public static void main(String arga[]){
     8                  
     9                           //测试记录函数,此处会发生ArrayIndexOutOfBoundsException
    10                            try{
    11                                String s[]=new String[2];
    12                                s[3]="li";
    13                            }catch(Exception e){
    14                                log(new Date(),e);
    15                            }
    16              }
    17              
    18              //声明将异常记录在文件方法
    19              public static void log(Date date,Exception e){
    20                  //记录异常文件名
    21                  String filename="E:/Exception.log";
    22                  
    23                  //声明缓冲输出流,提高操作效率
    24                  BufferedWriter bw=null;
    25                  try{
    26                      
    27                      //实例化输出对象
    28                      bw=new BufferedWriter(new FileWriter(filename));
    29                      
    30                      //声明格式化日期操作类,格式化日期格式
    31                      SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    32                      
    33                      //写入异常发生时间
    34                      bw.write(sdf.format(date)+"===");
    35                      
    36                      //写入异常信息
    37                      bw.write(e.toString());
    38                  }catch(IOException ex){
    39                      System.out.println("记录异常发生错误"+ex.toString());
    40                  }finally{
    41                      try{
    42                          if(bw!=null)
    43                              bw.close();
    44                      }catch(Exception ex){
    45                          System.out.println("关闭文件发生错误"+ex.toString());
    46                      }
    47                  }
    48              }
    49 }

    四,输出系统信息。

      1. 获取系统信息:             Propertes  prop=System.getProperties();
      2. 列出系统信息:             prop.list(new PrintStream("E:/sysinfo.txt");

    五,代码练习:

     1 import java.io.*;
     2 import java.util.Properties;
     3 
     4 
     5 public class SysInfo {
     6              public static void main(String args[]){
     7                  
     8                  //获取系统信息
     9                  Properties prop=System.getProperties();
    10                  
    11                  //声明输出流句柄
    12                  PrintStream ps=null;
    13                  try{
    14                      
    15                      //实例化对象
    16                      ps=new PrintStream("E:/sysinfo.txt");
    17                      
    18                      //将系统信息输出到指定流中
    19                      prop.list(ps);
    20                  }catch(IOException e){
    21                      System.out.println("写入错误"+e.toString());
    22                  }finally{
    23                      try{
    24                          if(ps!=null)
    25                              ps.close();
    26                      }catch(Exception e){
    27                          System.out.println("关闭文件错误!"+e.toString());
    28                      }
    29                  }
    30              }
    31 }

    六,常用到的系统信息:

      1. user.language=zh   用户的语言
      2. file.encoding=GBK  系统编码
      3. user.name=Thinkpad  用户名
      4. line.separator=          换行符
      5. os.name=Windows 8  操作系统
      6. path.separator=;       路径分割符
     
  • 相关阅读:
    hdoj Last non-zero Digit in N! 【数论】
    spin_lock &amp; mutex_lock的差别?
    20140514,微软5月14日公布8个安全补丁
    教你用笔记本破解无线路由器password
    SSL工作原理
    MS-SQLSERVER中的MSDTC不可用解决方法
    grub2手动引导ubuntu
    用递归翻转一个栈 Reverse a stack using recursion
    腾讯面试
    AngularJS移动开发中的坑汇总
  • 原文地址:https://www.cnblogs.com/xiaochongbojue/p/4045554.html
Copyright © 2011-2022 走看看