黑马程序员_java之IO流

IO流

IO流处理设备之间的数据传输,Java对数据的操作是通过流的方式,Java用于操作流的对象都在IO包中。

按操作数据分为:字节流、字符流;按流向分为:输入流、输出流。字符流融合了编码表。

字节流抽象基类:InputStream、OutputStream.;字符流抽象基类: Writer、Reader。

字符流读写操作:

子类名称都是以其父类作为子类名的后缀,流创建文件时,如文件已存在,则会覆盖该文件;想对已有文本文件续写,则可在FileWriter传递一个true参数,不覆盖已有文件,在文件末尾进行数据续写。flush和close区别:filush刷新流对象中缓冲中的数据,可继续使用;close刷新后关闭流资源。void write(char[] cbuf);  void write(String str);void write(String str, int off, int len) ;abstract  void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。void write(int c)写入单个字符。

凡是和设备数据发生数据关系的都有IO异常。

处理IO异常范例:fileWriter fw=null;

                      try{

                                   Fw=new FileWriter(“a.txt”);

                                   Fw.write(“abc”);

                          }

                         Catch(IOException e){   //异常处理e.toString() ,}

                  fnally{

            try{

                                          If (fw!=null){ Fw.close();}

                                    }

                                   Catch(IOException e){//异常处理 }

          }

字符流读取数据有3种操作。

读取方法:int read()  读取单个字符;int read(char[] cbuf)  将字符读入数组,读取的字符数; abstract  int read(char[] cbuf, int off, int len)

分别简写为 1、不需要缓冲区  int ch =0; while ((ch=fis.read())!=-1){Sop((char)ch)}  fis.close();

2、用数组做缓冲区char [] buf=new char [1024];int len =0; while((len =fis.read(buf))!=-1){ Sop(new String(buf,0,len);}fis.close();

注:若文件里有abcdefg  7个字符,缓冲区长度为3,则若不用循环,read(buf)四次,并打印数组Sop(new String(buf),则结果为abc,def,gef,gef,其中len结果为3,3,1,-1

3、用BufferedReader: BufferedReader bufr=new BufferedReader(fr); String line=null;while((line=bufr.readLine())!=null){ Sop(line);} bufr.close();          

缓冲区的出现提高了数据的读写效率,要结合流才可使用(创建一个流对象和文件相关联),在流的基础上对流的功能进行增强;

缓冲原理是对象里面封装了数组。字符流缓冲区对应的类:BufferedWriter、BufferedReader.字节流缓冲区对应的类:BufferedInputStream、BufferedOutputStream.。

BufferedWriter 特有void newLine() 写入一个行分隔符;BufferedReader特有方法String readLine()读取一个文本行。只返回回车符之前的数据内容,不返回回车符;

readLine()原理:read方法一次读一个方法,对象里面封装了数组,为了方便,定义StringBuilder容器

public String myReaderLine() 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();

    }

注:其实关闭缓冲区就是关闭缓冲区中流对象

装饰设计模式:想要对已有得对象进行功能增强时,可以定义类,将已有得对象传入,基于已有的功能,并提供加强功能,那么自定义的类称为装饰类。装饰类通常通过构造方法接收被装饰的对象。

装饰模式和继承区别:装饰比继承灵活,避免继承体系臃肿,且降低类与类之间的关系;装饰类因为增强已有功能,所以装饰类和被装饰类通常都是属于一个体系

小知识点:跟踪行号的缓冲字符输入流LineNumberReader是BufferedReader子类,其中setLineNumber设置行号,gerLineNumber得到行号。

字节流读写操作:

字节流:InputStream OutputStream

OutputStream 写入方法:void write(byte[] b) void write(byte[] b, int off, int len) abstract  void write(int b),要写字符串则str.getBytes()

InputStream 读方法 abstract  int read() ;int read(byte[] b)  ;int read(byte[] b, int off, int len)

写的时候不需要刷新fos.write(“abd”.getBytes),字符流底层用的是字节流缓冲区,字符流有个临时存储数据的数组,所以需要刷新,字节没使用指定缓冲区,故不需要刷新。

读有三种操作。分别简写为 1、不需要缓冲区 int ch =0; while((ch=fis.read())!=-1){ Sop((char)ch);}fis.close();

                                   2、一般用法 byte[] buf=new byte [1024];int len =0; while((len =fis.read(buf))!=-1){Sop(new String(buf,0,len);}fis.close(); 

                                   3、不常用法  byte [] buf=new byte [fis.available()];//定义一个刚好的数组  fis.read(buf); Sop(new String(buf);fis.close();

注:txt文件里有abcqq回车z则available为8个

字节流缓冲简单实例:

Pubic  static void copy () throwsTOException{

  BufferedInputStream bufis =new BufferedInputStream(new FileInputStream(“c:\\a.mp3”);

  BufferedOutputStream bufos =new BufferedOutputStream (new FileOutputStream(“c:\\b.mp3”);

       int by=0;

  while((by=bufis.read())!=-1){

       bufos.write(by);

  }

  bufos.colse();

  bufis.close();

}

自定义字节流的缓冲区 read和write特点

Class  MyBufferedInputStream

{

       Private InputStream in; 

  Private byte []=new byte[1024];

       Private int pos=0,count=0;

       MyBufferedInputStream (InputStream in){

       This.in=in;}

  Public void myClose() throws IOException{

       in.close();

  }

  Public int myRead () throws IOException{//问题1返回类型为什么是int而不是byte

         If(count= =0){

              count=in.read(buf);

              byte b=buf[pos];

              If(count <0)

                     return -1;

              pos=0;

              count--;

              pos++;     

              return b&255;// 问题 2为什么 要&&上255

    }

    else if(count >0){

              byte b=buf[pos];

              count--;

              pos++;   

              return b&Oxff;

    }

    return -1;

  } 

}

问题1:返回的也是byte的话碰到11111111时候会停止读取,而返回的是int问题得到转化。

问题2:返回的是int话,由1个字节变成4字节,类型提升,不过还是-1,但是与上255的话就会变成前3字节全由0组成后1字节不变,这样保留了自己数据不变,又可避免-1的出现。

Read方法 补0向上提升,保证不会出现-1情况

Write方法 强转动作,把最低8位写出去,将指定字节写出去   

读取键盘录入

System.in 对应标准输入设备 默认键盘,read方法阻塞式方法

System.out 对应标准输出设备 默认控制台

例:键盘录入a若读三次结果97,13,10,类型提升

转换流(字符流的子类):转换流什么时候使用?字节和字符之间的桥梁,涉及到字符编码转换 

读取转换流(字节通向字符)InputStreamReader有子类FileReader

写入转换流(字符通向字节)OutputStreamWriter 如录字符存字节;有子类FileWriter

例:BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));

   BufferedWriter bufw=new BufferedWriter (new OutputStreamWriter (System.out)); 

流操作规律:

三个明确:

1、  明确源和目的 源:输入流 读 InputStream Reader

                  目的:输出流 读 OutputStream Writer

2、  操作数据是否纯文本? 是: 字符流  否:字节流

3、  当体系明确后,明确哪个具体对象,通过设备区分

     源设备:内 存、硬盘、键盘  ArrayStream  FileStream  System.in

目的设备:内 存、硬盘、控制台  ArrayStream  FileStream  System.out

4、有时候提高效率使用缓冲技术

改变标准输入输出设备

System.setIn(InputStream   in), System.setOut (PrintStream out)

System.setIn(new FileInputStream(“a.txt”));//将输入设备变成文本文件

System. setOut (new PrintStream(“a.txt”));//将输出设备变成文本文件 

异常日志信息 log 4j

try{}

Catch(Exception e){

  try{

       Date d=new Date();

       SimpleDateFormat sdf=new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);

  String s=sdf.format(d);

       PrintStream ps=new PrintStream(“exception.log”);

       Ps.println(s);

  System. setout(ps);}

  Catch(IOException ex){

              Throw new RuntimeException(“创建失败”);}

  e.PrintStackTrace(System.out);//直接写入打印流

}

 

posted on 2013-01-28 18:13  念满  阅读(209)  评论(0编辑  收藏  举报