Java笔记5 IO<2>缓冲流、转换流


19天-03-IO流(通过缓冲区复制文本文件)

l  字符读取流缓冲区:

该缓冲区提供了一个一次读取一行的方法readLine,方便与对文本数据的获取。当返回null时,表示独到文件末尾。

l  readLine方法返回时,只返回回车符之前的数据内容,并不返回回车符。在写入数据时,需要换行。

 

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

 

public class BufferedCopy {

 

    public static void main(String[] args) {

        BufferedReader bufr = null;

        BufferedWriter bufw = null;

        try {

bufr = new BufferedReader(new FileReader("buf.txt"));//创建//字符缓冲读取流

bufw = new BufferedWriter(new FileWriter("des.txt"));//创建//字符缓冲写入流。

           

            String line = null;

            while((line=bufr.readLine())!=null){//readLine方法不会读取行//终止符

                bufw.write(line);//写一行,须换行。

                bufw.newLine();//换行

                bufw.flush();

            }

        } catch (IOException e) {

            throw new RuntimeException("读写失败!");

        }finally{

            if(bufr!=null){

                try {

                    bufr.close();

                } catch (IOException e) {

                    thrownew RuntimeException("文件读取失败!");

                }

            }

            if(bufw!=null){

                try {

                    bufw.close();

                } catch (IOException e) {

                    thrownew RuntimeException("文件写入失败!");

                }

            }

        }

    }

}

 

 

19天-05-IO流(MyBufferedReader)

l  模拟自定义缓冲区

import java.io.FileReader;

import java.io.IOException;

 

public class MyBufferedReader {

    private FileReaderr;

    public MyBufferedReader(FileReader r){

        this.r = r;

    }

   

    //可以一次读一行数据的方法

    public String MyReaderLine()throws IOException{

        StringBuilder sb = new StringBuilder();

        int ch = 0;

        while((ch=r.read())!=-1){

            if(ch=='\r'){

                continue;

            }

            if(ch=='\n'){

                return sb.toString();

            }else{

                sb.append((char)ch);            

            }

        }

        return null;

    }

   

    public void myClose() throws IOException{

        r.close();

    }  

}

 

 

19天-06-IO流(装饰设计模式)

l  装饰设计模式:

当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入(通过构造函数),基于已有的功能,并提供加强功能。那么自定义的该类成为装饰类。

l  装饰类通常会通过构造方法接受被装饰的对象。并基于被装饰的对象的功能,提供更强的功能。

示例:

class Person{

    public void chifan(){

        System.out.println("吃饭");

    }

}

 

public class SuperPerson {

    private Personp;

    public SuperPerson(Person p) {

        this.p = p;

    }

    public void superChiFan(){//通过提供已有对象的方法(不对该方法重写),再对//该功能进行了加强。

        System.out.println("开胃酒");

        p.chifan();

        System.out.println("甜点");

    }//功能加强:除了吃放,还能喝酒、吃甜点。

}class Person{

    public void chifan(){

        System.out.println("吃饭");

    }

}

 

public class SuperPerson {

    private Personp;

    public SuperPerson(Person p) {

        this.p = p;

    }

    public void superChiFan(){//通过提供已有对象的方法(不对该方法重写),再对该功能进行了加强。

        System.out.println("开胃酒");

        p.chifan();

        System.out.println("甜点");

    }//功能加强:除了吃放,还能喝酒、吃甜点。

}

Ÿ   19-05的举例也是装饰设计模式的例子。

²  装饰模式与继承比较,要比继承灵活的多,避免了继承体系的臃肿(继承必须继承父类成员,而装饰类通过构造方法传入对象后,可以对该对象的一个或多个方法的功能进行增强,这样必然会很灵活),而且降低了类与类之间的关系。

²  装饰类因为增强了已有对象,具备的功能和已有的是相同的,只不过提供了更抢的功能。所以装饰类和被装饰类通常都是属于一个体系中的。

 

 

19天-10-IO流(MyLineNumberReader)

此例的父类为19-05:MyBufferedReader。

import java.io.FileReader;

import java.io.IOException;

 

public class MyLineNumberDemo1 extends MyBufferedReader {

    private int lineNumber = 1;

    public MyLineNumberDemo1(FileReader r){

        super(r);

    }

   

    //可以一次读一行数据的方法

    public String MyReaderLine()throws IOException{

        lineNumber++;//每读一行加一次

        return super.MyReaderLine();//引用父类的MyReaderLine()方法

    }

    public void setMyLineNumber(int lineNumber){

        this.lineNumber = lineNumber;

    }

    public int getMyLineNumber(){

        return this.lineNumber;

    }  

}

 

 

19天-12-IO流(拷贝图片)

l  复制一个文件。

思路:

1)       用字节流读取流对象和文件关联。

2)       用字节流写入流对象创建一个图片文件,用于存储获取到的图片数据。

3)       通过循环读写,完成数据的存储。

4)       关闭资源。

注:为了省事,代码直观,就不用try/catch语句了,但是开发中不能这样写。

public class CopyFile12Demo {

 

  public static void main(String[]args)throws IOException {

      FileInputStream fis = new FileInputStream("C:\\baidu player\\归宿.mp3");

      FileOutputStream fos = new FileOutputStream("C:\\baidu player\\3.mp3");

      //copyStreamFile2(fis,fos);

      copyStreamFile2(fis, fos);//运行结果表明:方法2的拷贝效率比方式一高。

  }

 

  public static voidcopyStreamFile1(FileInputStream fis,FileOutputStream fos)throws IOException{

      long start =System.currentTimeMillis();

       int ch = 0;

       while((ch=fis.read())!=-1){

           fos.write(ch);

      //fos.write((char)ch);javaAPI中没有接收字符参数的write方法,这里

      //只不过先强制将int类型强制转换为char类型,再由jvm自动向上转型成int类型。

           //这种方式多此一举。

       }

       fis.close();

       fos.close();

       long end = System.currentTimeMillis();

       System.out.println("耗时:"+(end-start));

  }

 

  public static void copyStreamFile2(FileInputStreamfis,FileOutputStream fos) throws IOException{

      long start =System.currentTimeMillis();

       byte[] buf =newbyte[1024];

       int len = 0;

       while((len=fis.read(buf))!=-1){

           fos.write(buf,0,len);

           fos.flush();//刷新为了防止缓冲区数据溢出,造成数据丢失。

       }

       fis.close();

       fos.close();

       long end = System.currentTimeMillis();

       System.out.println("耗时:"+(end-start));

  }

}

 

 

19天-13-IO流(字节流的缓冲区)

l  练习,利用字节缓冲流拷贝Mp3

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.Scanner;

 

public class CopyFile12Demo1 {

      

       publicstatic void main(String[] args) {       

              Scanner s = new Scanner(System.in);

              System.out.println("请输入要拷贝的文件路径名:");

              String src = s.nextLine();

              System.out.println("请输入目的文件路径名:");

              String des = s.nextLine();

              try {

                     copy1(src,des);

              } catch (IOException e) {

                     e.printStackTrace();

              }

       }

       publicstatic void copy1(String fisStr,String fosStr) throws IOException{

              BufferedInputStream bufIn= null;

              BufferedOutputStream bufOut= null;

              try {

                     bufIn= new BufferedInputStream(new FileInputStream(fisStr));

                     bufOut= new BufferedOutputStream(new FileOutputStream(fosStr));

                     byte[]buf = new byte[1024];

                     intlen = 0;

                     while((len=bufIn.read(buf))!=-1){

                            bufOut.write(buf,0,len);

                            bufOut.flush();

                     }

              } catch (FileNotFoundException e) {

                     thrownew RuntimeException("读写失败!");

              }finally{

                     if(bufIn!=null){

                            try {

                                   bufIn.close();

                            } catch (IOException e2) {

                                   thrownew RuntimeException("读取失败!");

                            }

                     }

                     if(bufOut!=null){

                            try {

                                   bufOut.close();

                            } catch (Exception e2) {

                                   thrownew RuntimeException("写入失败");

                            }

                     }

              }    

       }

}

 

 

19天-14-IO流(自定义字节流的缓冲区-read和write的特点)

自定义myRead()方法。(通过视频讲解,做了详尽注释,能看懂了)

import java.io.IOException;

import java.io.InputStream;

 

public class MyBufferedInputStream {

    private InputStreamin;

    private byte[] buf = newbyte[1024];

    private int pos = 0,count = 0;

   

    public MyBufferedInputStream(InputStream in){

        this.in = in;

    }

   

    //<1>首次执行myRead方法(此时,count=0,pos=0)

    //<5>判断(myRead()!=-1)true,接着循环

    //此时,(count=buf.length-1)>0pos=1;

    //<9>…

    public int myRead() throws IOException{

        if(count==0){

            count = in.read(buf);//<2>count是返回的字节数。

            if(count<0){

                return -1;

            }

            pos = 0;

            byte b =buf[pos];//<3>读取第一个字节

           

            count--;//<4>字节数-1

            pos++;//<4>//索引+1pos=1;

            return b&255;//<4>返回第一个字节(字节的8位数据保持不变,存于int//数据低8

        }else if(count>0){//<6>(count=buf.length-1)>0,执行此语句块。

            byte b =buf[pos];//<7>读取缓冲区索引为1的字节数据,并赋值给b

            count--;//<8>count = buf.length-2;

            pos++;//<8>pos = 2

            return b&255;//<8>返回字节&255转换后的整数值

            /*b&255的原因。防止当b=1111-1111时,直接返回b,向上转型成

             * 1111-1111 1111-11111111-1111 1111-1111后,在判断是否*myRead()!=-1

             * 时,false,而使循环终止。b&255好处,1111-1111&255,可以得到:

             * 0000-0000 0000-00000000-0000 1111-1111,不会使*while(myRead()!=-1)

             * 终止,能继续数据的读写。

             * */

        }

        return -1;

    }

   

    public void myClose() throws IOException{

        in.close();

    }

   

}

 

 

19天-16-IO流(读取转换流)

l  字节流转换成字符流的举例

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

 

public class InputStreamReaderDemo {

 

    public static void main(String[] args)throws IOException {

        //获取键盘录入对象

        InputStream in = System.in;

        //将字节流对象转成字符流对象,使用转换流。InputStreamReader

        InputStreamReader isr = newInputStreamReader(in);

        //为了提高效率,将字符串进行缓冲技术高效操作。使用bufferedReader

        BufferedReader bufr = new BufferedReader(isr);

        String line = null;

        while((line=bufr.readLine())!=null){

            if(line.equals("over")){

                break;

            }

            System.out.println(line.toUpperCase());

        }

        bufr.close();

    }

}

 

 

19天-17-IO流(写入转换流)

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

 

public class OutputStreamReaderDemo {

    //为简化代码,没写try/catch语句。

    public static void main(String[] args)throws IOException {

        BufferedReader bufr = new BufferedReader(newInputStreamReader(System.in));

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

        String line = null;

        while((line=bufr.readLine())!=null){

            if(line.equals("over")){

                break;

            }

            bufw.write(line.toUpperCase());

            bufw.newLine();

            bufw.flush();

        }

        bufr.close();

        bufw.close();

    }

}

 

 

19天-18-IO流(流操作规律-1)

l  流操作规律

1.        源:键盘录入。

目的:控制台。

 

2.        需求:把键盘录入的数据存储到一个文本中。

源:键盘。

目的:文件。

 

3.        需求:将一个文本的数据打印在控制台。

源:文件。

目的:控制台。

 

流操作的基本规律:

       最痛苦的就是流对象高很多,不知道该用哪一个。

通过两个明确来完成。

1.      明确源和目的。

源:输入流。InputStream Reader

目的:输出流。OutputStream Writer

2.      操作的数据是否是纯文本。

是:字符流。

不是:字节流。

3.      当体系明确后,在明确要使用哪一个具体的对象。

通过设备来进行区分:

原设备:内存,硬盘,键盘。

目的设备:内存,硬盘,控制台。

 

 

19天-20-IO流(改变标准输入输出设备)

示例:

System.setIn(new FileInputStream(“PersonDemo.java”));

System.setOut(new FileOutputStream(“zzz.txt”));

改变标准输入输出设备后,就会从指定的文件读取数据,和向执行文件写入数据了。

 

 

19天-21-IO流(异常的日志信息)

import java.io.IOException;

import java.io.PrintStream;

importjava.text.SimpleDateFormat;

import java.util.Date;

 

public class ExceptionInfo {

   

    public static void main(String[] args)throws IOException {

        try {

            int[] arr =newint[2];

            System.out.println(arr[3]);

        } catch (Exception e) {

            try {

                //System.setOut(newPrintStream("exception.log"));//<1>

                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");

                System.setOut(ps);

                ps.println(d.toString());      

            } catch (IOException e1) {

                thrownew RuntimeException("日志文件创建失败");

            }

            //e.printStackTrace(System.out);//<1>

        }

    }

}

//打印的异常信息会保存到当前目录的exception.log文件中。

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值