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.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
    }
    
//可以一次读一行数据的方法
    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
    }
    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
    }
    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
    public MyLineNumberDemo1(FileReader r){
        super(r);
    }
    
//可以一次读一行数据的方法
    public String MyReaderLine()throws IOException{
lineNumber++;//每读一行加一次
        return  super.MyReaderLine();//引用父类的MyReaderLine()方法
    }
    public  void setMyLineNumber(int lineNumber){
        this.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);
//刷新为了防止缓冲区数据溢出,造成数据丢失。
       }
       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
    
    public MyBufferedInputStream(InputStream in){
        this.in
    }
    
//<1>首次执行myRead方法(此时,count=0,pos=0)。
//<5>判断(myRead()!=-1),true,接着循环
//此时,(count=buf.length-1)>0,pos=1;
    //<9>…
    public  int myRead() throws IOException{
        if(count==0){
count =  in.read(buf);//<2>count是返回的字节数。
            if(count<0){
                return -1;
            }
pos
            byte b =buf[pos];//<3>读取第一个字节
            
count--;//<4>字节数-1。
pos++;//<4>//索引+1,pos=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文件中。