首页 > 代码库 > IO流基础

IO流基础

  IO流,也称为数据流,用于处理设备之间的数据传输。
  JAVA对数据的操作就是通过流的方式,而流分为两种:字符流,字节流

字符流:

  可以内部制定码表,处理文字很方便,字符流里的基类是Reader,Writer
字节流:

  操作字节数据。和字符流差不多,基类是InputSteram,OutputStream,如果不使用缓冲区,不需要flush()方法,查看父类方法,使用子类建立对象。

  IO包中子类名称后缀就分明了字节流和字符流,前缀说明了功能,缓冲区的出现是为了提高流的效率,在创建缓冲区之前要先有流对象,只要用到缓冲区就要用到flush()刷新方法。关闭缓冲区就会关闭缓冲区中调用的流对象。

    bufferedWriter缓冲区提供跨平台换行符方法newLine();
    bufferedReader缓冲区提供一次读取一个文本行的方法readLine();不包含终止符,读到文件末尾返回null,加强了原有功能,如果想提高效率就使用缓冲区,Bufferedxxx。
装饰设计模式:
  当想要对已有的对象进行功能增强时,定义一个类将已有对象传入,基于已有功能,提供加强功能,那么这个自定义的类就称为装饰类,装饰模式比继承要灵活,避免继承体系臃肿,降低类与类的关系,装饰类和被装饰类通常是一个体系的。

  因为增强已有对象,具备的功能和已有的是相同的,只不过是加强功能,通常通过构造方法(接收被装饰的对象),基于传入对象的功能提供更强的功能方法。

流操作的基本规律:
  最痛苦的就是流对象有很多,不知道该用哪一个。

  通过三个明确来完成

    1,明确源和目的。
      源:输入流。InputStream Reader。
      目的:输出流。OutputStream Writer。
    2,操作的数据是否是纯文本。
      是:字符流。
      不是:字节流。

    3,当体系明确后,在明确要使用哪个具体的对象。
      通过设备来进行区分:
      源设备:内存,硬盘,键盘。
      目的设备:内存,硬盘,控制台。

  流操作的只有数据,而数据最明显的体现形式就是文件,而文件包含很多信息,属性,想操作文件的话,java就把文件封装成了对象File类,方便对文件或者文件夹的属性进行操作。

  properties是Hashtable的子类,具备Map集合的特点,存储的键值对都是字符串,是集合中和IO技术结合的容器,用于键值对形式的配置文件。

 

  字节流的两个顶层父类:

    1.InputStream   2.outputStream

  字符流的两个顶层父类:

    1.Reader    2.Writer

  这些体系的子类都是已父类名做为后缀,而前缀是该对象的功能。

 

  字符流:

  简单例子:将一个字符串写入到文件中

 1   //创建一个可以往文件中写入字符数据的字符流输出对象 2   FileWriter fe = null; 3     try { 4         //在创键对象时必须要明确该文件的存储目的地 5         //如果目的地存在该文件,则会被覆盖 6         //如果构照文件中加入true,则可以对文件进行续写 7         fe=new FileWriter("F:/1.txt",true); 8         //调用write写入数据 9             fe.write("asjhgfajkshgfaksjdfg");10         } catch (IOException e) {11             e.printStackTrace();12         }finally{13             try {//关闭流,关闭资源,在关闭前会调用flush();刷新缓冲区14               fe.close();15             } catch (IOException e) {16               e.printStackTrace();17             }18     }19     //将硬盘中的文件读取然后输入到控制台中:20     //1.创建读取流对象21     FileReader fr=null;22     try{ 23         //2.在读取的时候一定要 被明确被读取的文件,确保这个文件存在,不然会发生异常24         fr=new FileReader("f:/1.txt");25         int aa=0;26         while((aa=fr.read())!=-1){27         System.out.println((char)aa);28         }29   . . .  ..  . . .30   //用数组读取文件:31   //1.创建读取流对象32     FileReader fr=null;33     try{ 34         //2.在读取的时候一定要 被明确被读取的文件,确保这个文件存在,不然会发生异常35         fr=new FileReader("f:/1.txt");36         char [] ch=new char[1024];37         int leng=0;38         while((leng=fr.read(ch))!=-1){39         System.out.println(new String(ch,0,leng));40      }    

  如果字符串中需要换行,可以在字符串中加入常量:(根据系统资源获取对应的换行符)
  private static final String LINE_SEPARATOR =System.getProperty("line.separator");
  IO异常:在用读写流对象调用colse()的时候一定要加判断判断对象不等于null否则会抛空指针异常

  字符流缓冲区对象:BuffredReader , BuffredWriter
  在字符流缓冲区中:
    newLine():写入一个行分隔符。行分隔符字符串由系统属性 line.separator 定义,并且不一定是单个新行 (‘\n‘) 符。
    Newline():只有BuffredWriter对象具备。
    readLine():读取一个文本行,一次读取一行数据,遇到换行符就终止,返回读取到的字符串,如果读取到流的末尾就返回null。
    readKine():方法只有BuffredReader具备。

  使用方法:

  1 public static void main(String[] args) throws IOException {  2        //字符流关联文件  3         FileReader fr=new FileReader("f:/1.txt");  4         FileWriter fw=new FileWriter("f:/2.txt");  5         BufferedReader br=new BufferedReader(fr);  6         BufferedWriter bw=new BufferedWriter(fw);  7         char [] ch=new char[1024];  8         int leng=0;  9         //使用缓冲区读取数据,从缓冲区中读取数据 10         while((leng=br.read(ch))!=-1) 11         { 12             //使用缓冲区写入数据到内存中 13             bw.write(ch, 0, leng); 14         } 15         //关闭缓冲区,实际上就是关闭了流对象 16         br.close(); 17         bw.close(); 18     } 19 自定义缓冲区: 20 public class MybufferReader { 21    private Reader r; 22    //定义一个数组作为缓冲区 23    private char [] ch=new char[1024]; 24    //定义一个指针用于操作数组中的元素,当操作到最后一个元素时指针归零 25    private int pos=0; 26    //定义一个计数器,用于记住缓冲区的数据个数,当缓冲区中数据减到零,就从源中继续获取数据到缓冲区中 27    private int count=0; 28    public MybufferReader(Reader r) { 29          this.r=r; 30    } 31     /* 32      该方法一次从缓冲区中取一个字符 33   */ 34     public int myReader() throws IOException 35     { 36         //从源中获取一批数据到缓冲区中,只有count为0时。 37         if(count==0) 38         { 39             count=r.read(ch); 40             pos=0; 41         } 42         //当源中的数据取完时候返回负一 43         if(count<0) 44              return -1; 45          46           char ch1=ch[pos];//读取缓冲区中数据 47           pos++;//数组的指针+1 48           count--;//缓冲区中数据的个数-1     49           return ch1; 50  51     } 52     public String myReaderLine() throws IOException   53     { 54         StringBuilder sb=new StringBuilder(); 55         int ch=0; 56         while((ch=myReader())!=-1) 57         { 58             if(ch==‘\r‘) 59                 continue; 60             if(ch==‘\n‘) 61                 return sb.toString(); 62             //将从缓冲区中读到的字符存储到转存行数据的缓冲区中 63             sb.append((char)ch); 64         } 65         if(sb.length()!=0) 66             return sb.toString(); 67         return null; 68     } 69     public void mycolse() throws IOException 70     { 71         r.close(); 72     } 73      74 } 75 装饰设计模式:  76    对一组对象的功能进行增强的时候,就可以使用该模式来解决问题。 77 例如:public class PersonDemo { 78     public static void main(String[] args) { 79         Person p=new Person(); 80         p.chifan(); 81         newperson p1=new newperson(p); 82         p1.chifan(); 83         newperson2 p2=new newperson2(); 84         p2.chifan(); 85     } 86 } 87 class Person 88 { 89     public void chifan() 90     { 91         System.out.println("吃饭"); 92     } 93 } 94 //这个类的出现是为了增强Person的功能出现的 95 class newperson 96 { 97     private Person p; 98     //构造方法中传入Person对象 99     public newperson(Person p) {100     this.p=p;101     }102     //增强chifan方法103     public void chifan()104     {105         System.out.println("喝酒");106         p.chifan();107         System.out.println("吃甜点");108     }    109 }110 //这个类继承于Person111 class newperson2 extends Person112 {113     public void chifan()114     {115         System.out.println("喝酒");116         super.chifan();117         System.out.println("吃甜点");118     }119 }120 装饰设计模式和继承都能实现这一特点,特点:只为提高功能,进行的继承导致继承体系越来越臃肿,不够灵活,而装饰比继承灵活。121 BufferedReader的子类LineNumberReader的基本使用。122 例子: public static void main(String[] args) throws IOException {123    FileReader fr=new FileReader("ArrayListTest.java");124    LineNumberReader lin=new LineNumberReader(fr);125    String str=null;126    //一次读取一行127    while((str=lin.readLine())!=null)128    {//输出行号和行内容129        System.out.println(lin.getLineNumber()+":"+str);130    }131 }

IO流基础