IO流1

在这里插入图片描述
FileWriter

/**
*输入流和输出流是相对于内存设备而言
* 
* 字符流的由来:
* 字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字。
* 再对这个文字进行操作,简单说:字节流+编码表
* --------------------------------------
* 字节流的两个顶层父类:
* 1.InputStream   2.OutputStream
* 这些体系的子类都以父类名作为后缀。
* 而且子类名的前缀就是该对象的功能。
* 
* 字符流的两个顶层父类:
* 1.Reader   2.Writer
*/
//需求:将一些文字存储到硬盘
//记住:
public static void demo_1() throws IOException{
   //创建一个可以往文件中写入字符数据的字符输出流对象
   /**
    * 既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(用于存储数据的目的地)
    * 如果文件不存在,则会自动创建。
    * 如果文件存在,则会被覆盖。
    * 
    * 如果构造函数中加入true,可以实现对文件进行续写
    */
   FileWriter fw = new FileWriter("E:/1.txt",true);
   /**
    * 调用Writer对象中的write(String)方法,写入数据
    * 其实数据写入到临时存储缓冲区中
    */
   String LINE_SEPARATOR = System.getProperty("line.separator");
   fw.write("hello"+LINE_SEPARATOR+"world");
   /**
    * 进行刷新,将目标写入到目的地中
    */
   // fw.flush();
   /**
    * 关闭流,关闭资源  在关闭前会调用flush刷新缓存中的数据到目的地
    */
   fw.close();
}

FileWriter–IO异常处理

//IO异常处理
public static void demo_2() throws IOException{
    FileWriter fw = null;
    try{
        fw = new FileWriter("K:/1.txt",true);
        String LINE_SEPARATOR = System.getProperty("line.separator");
        fw.write("hello"+LINE_SEPARATOR+"world");  
    }
    catch(IOException e){
        System.out.println(e.toString()+"error");
    }
    finally{
        if(fw!=null)
            try{
                fw.close();
            }catch(IOException e){
                throw new RuntimeException("关闭失败");
            }
    }
}

读取方式一

//需求:读取一个文本文件,将读取到的字符打印到控制台
//同上,找到FileReader
public static void demo_3() throws IOException{
    //1.创建读取字符流对象
    /**
     * 在创建读取流对象时,必须要明确被读取的文件。一定要确定该文件是存在的
     * 用一个读取流关联一个已存在的文件。
     */
    FileReader fr = new FileReader("E:/1.txt");
    //用Reader中的read方法读取字符
    int ch = 0;
    while((ch=fr.read())!=-1){
        System.out.println((char)ch);
    }
    fr.close();
}

读取方式二

public static void demo_4() throws IOException{
FileReader fr = new FileReader("E:/1.txt");
/**
 * 使用read(char[])读取文本文件数据
 */
char[] buf = new char[3];
// int num = fr.read(buf);//将读到的char字符存储到数组中
// System.out.println(num+":"+new String(buf));
// fr.close();
int len = 0;
while((len=fr.read(buf))!=-1){
    System.out.println(new String(buf,0,len));
}
fr.close();
}

将盘一个文件复制到d盘中

//作用:将盘一个文件复制到d盘中
public static void demo_1() throws IOException{
    //1.读取一个已有的文本文件,使用字符读取流和文件相关联
    FileReader fr = new FileReader("E:/1.txt");
    //2.创建一个目的,用于存储读到数据。
    FileWriter fw = new FileWriter("E:/2.txt");
    //3.频繁的读写操作。
    int ch = 0;
    while((ch=fr.read())!=-1){
        fw.write((char)ch);
    }
    //4.关闭流资源。
    fw.close();
    fr.close();
}

复制文本文件

//复制文本文件
public static void demo_2(){
    FileReader fr = null;
    FileWriter fw = null;
    try{
        fr = new FileReader("E:/1.txt");
        fw = new FileWriter("E:/3.txt");
        //创建一个临时容器,用于缓存读取到的字符。
        char[] buf = new char[1024];
        //定义一个变量记录读取到的字符数,其实就是往数组里装的字符个数
        int len = 0;
        while((len=fr.read(buf))!=-1){
            fw.write(buf,0,len);
        }
    }
    catch(Exception e){
        System.out.println("读写失败");
    }
    finally{
        //关闭流
        if(fr!=null){
            try{
                fr.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        if(fw!=null){
            try{
                fw.close();
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    }
}

字符流缓冲区BufferedWriter

//字符流缓冲区BufferedWriter
    //      bufw.newLine();
public static void demo_3() throws IOException{
    //缓冲区的出现提高了对数据的读写效率
    //对应类
    //BufferedWriter :将文本写入字符输出流,缓冲各个字符,从而提供单个字符,数组和字符串的高效写入。
    //可指定缓冲区的大小,也可默认
    //BufferedReader :从字符输入流中读取文本,缓冲各个字符,从而实现字符,数组和行(文本特有的单位)的高效读取
    //缓冲区要结合流才能使用
    FileWriter fw = new FileWriter("F:/buf.txt");
    //为了提高写入效率,使用了字符流缓冲区。
    //创建了一个字符写入流的缓冲区对象,并和指定要被缓冲的流对象相关联
    BufferedWriter bufw = new BufferedWriter(fw);
    //使用缓冲区的写入方法将数据先写入到缓冲区中。
    bufw.write("hello buff");
    bufw.newLine();//bufw.write(System.lineSeparator());
    bufw.write("xixixi");
    ///fw.write("hello demo");
    for(int i=0;i<=4;i++){
        bufw.write("abcde"+i);
        bufw.newLine();
        bufw.flush();
    }
    //使用缓冲区的刷新方法将数据刷到目的地中
    // bufw.flush();
    //关闭缓冲区
    ///fw.close();
    bufw.close();//这时fw流也被关闭了
}

字符流缓冲区BufferedReader

//字符流缓冲区BufferedReader
    //      bufr.readLine();使用了读取缓冲区的read()方法,将读取到的字符进行缓冲并判断换行标记,将标记前的缓冲数据变成字符串返回。
public static void demo_4() throws IOException,FileNotFoundException{
    FileReader fr = new FileReader("F:/buf.txt");
    BufferedReader bufr = new BufferedReader(fr);
    String line = null;
    while((line=bufr.readLine())!=null){
        System.out.println(line);
    }
    // char[] buf = new char[1024];
    // int len = 0;
    // while((len=fr.read(buf))!=-1){
    //     System.out.println(new String(buf,0,len));
    // }
    fr.close();
    bufr.close();
}

字符流-缓冲区-复制文本文件

//字符流-缓冲区-复制文本文件
public static void demo_5() throws IOException{
    FileReader fr = new FileReader("F:/buf.txt");
    BufferedReader bufr = new BufferedReader(fr);
    FileWriter fw = new FileWriter("F:/buf_copy.txt");
    BufferedWriter bufw = new BufferedWriter(fw);
    /*
    int ch = 0;
    while((ch=bufr.read())!=-1){
        bufw.write(ch);
    }
    */
    String line = null;
    while((line=bufr.readLine())!=null){
        bufw.write(line);//line不带换行符
        bufw.newLine();
        bufw.flush();
    }
    bufw.close();
    bufr.close();
}

根据readLine()原理模拟readLine()方法

//根据readLine()原理模拟readLine()方法
    //自定义读取缓冲区
    /*
    分析:
    缓冲区中无非就是封装一个数组。
    并对外提供了更多的方法对数组进行访问。
    其实这些方法最终操作的都是数组的指针

    缓冲的原理:从源中获取一批数据装入缓冲区中,再从缓冲区中不断取出一个一个数据,
    当此次取完后,再从源中继续取一批数据进入缓冲区。
    当源中的数据被取光时,用-1进行标记。
    */
class myBufferReader{
    private FileReader r;
    //定义一个数组作为缓冲区
    private char[] buf = new char[1024];
    //定义一个指针操作数组中的元素.当操作到最后一个元素后,指针应该归零。
    private int pos = 0;
    //定义一个计数器,用于记录缓冲区中的数据个数,当该数据减到零,就从源中继续获取数据到缓冲区中。
    private int count = 0;
    myBufferReader(FileReader r){
        this.r = r;
    }
    //该方法一次从缓冲区中获取一个字符
    public int myRead() throws IOException{
        /*
        1.从源中获取一批数据到缓冲区中.需要先做判断,计数器是不是为0
         */
        if(count==0){
            count = r.read(buf);
            //每次获取数据到缓冲区后,角标归0
            pos = 0;
        }
        if(count<0){
            return -1;
        }
        char ch = buf[pos];
        pos++;
        count--;
        return ch;
    }
    public String myReadLine() throws IOException{
        StringBuilder sb = new StringBuilder();
        int ch = 0;
        while((ch = myRead())!=-1){
            if(ch=='\r')
                continue;
            //将从缓冲区读到的字符存储到缓存行数据的缓冲区中
            else if(ch=='\n')
                return sb.toString();
            sb.append((char)ch);
        }
        return null;
    }
    public void myclose() throws IOException{
        r.close();
    }
}

试用myBufferReader

//试用myBufferReader
public static void demo_6() throws IOException{
   FileReader fr = new FileReader("F:/buf.txt");
   myBufferReader bufr = new myBufferReader(fr);
   String line = null;
   while((line=bufr.myReadLine())!=null){
       System.out.println(line);
   }
   // char[] buf = new char[1024];
   // int len = 0;
   // while((len=fr.read(buf))!=-1){
   //     System.out.println(new String(buf,0,len));
   // }
   //fr.close();
   bufr.myclose();
}

字符流-缓冲区-装饰设计模式
什么是装饰

//类
class Person{
    Person(){}
    public void eat(){
        System.out.println("eat!");
    }
}
//这个类的出现是为了增强Person
class newPerson{
    private Person p;
    newPerson(Person p){
        this.p = p;
    }
    public void eat(){
        System.out.println("dessert");
        System.out.println("eat!");
    }
}
//字符流-缓冲区-装饰设计模式
/**
 * 对一组对象功能进行增强时,就可以使用该模式进行问题的解决。
 */
/*
装饰和继承都能实现一样的特点:进行功能的扩展增强。
区别:
    首先有一个继承体系。
    Writer
        |--TextWriter:用于操作文本
        |--MediaWriter:用于操作媒体
    想要对操作动作进行效率上的提高。
    按照面向对象,可以通过继承对具体的进行功能的扩展。
    效率提高需要加入缓冲技术。
    Writer
        |--TextWriter:用于操作文本
            |--BufferTextWriter:加入了缓冲技术的操作文本对象
        |--MediaWriter:用于操作媒体
            |--BufferMediaWriter:
    这样就加入了缓冲技术,但是这样做并不理想。
    如果这个体系进行功能扩展,又多了流对象,这个流要提高效率也要产生子类,
    子类为提高功能进行的继承导致继承体系越来越臃肿,不够灵活。
    重新思考这个问题,
    既然加入都是同一种技术--缓冲,
    前一种是让缓冲和具体的技术相结合。
    可不可以让缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲相关联。
    class Buffer{
    Buffer(TextWriter w){}
    Buffer(MediaWriter w){}
    }
    class BufferWriter extends Writer{
    BufferWriter(Writer w){}
    }
    体系变为这样:
    Writer
        |--TextWriter:用于操作文本
        |--MediaWriter:用于操作媒体
        |--BufferWriter:用于提高效率
    所以,装饰比继承灵活
    特点:装饰类和被装饰类都必须所属同一个接口或者父类。
*/
public static void demo_7(){
  	 Person p = new Person();
     p.eat();
     newPerson p1 = new newPerson(p);
     p1.eat();
 }

字符流-缓冲区-LineNumberReader

//字符流-缓冲区-LineNumberReader
public static void LineNumberReaderDemo() throws IOException{
    FileReader fr = new FileReader("F:/buf.txt");
    LineNumberReader lnr = new LineNumberReader(fr);
    String line = null;
    while((line=lnr.readLine())!=null){
        System.out.println(lnr.getLineNumber()+"::"+line);
    }
}

字节流-操作文件基本演示

//字节流-操作文件基本演示
public static void demo_write() throws IOException{
    //1.创建字节输出流对象。用于操作文件
    FileOutputStream fos = new FileOutputStream("F:/buf.txt");
    //2.写数据
    fos.write("hello".getBytes());
    fos.close();//关闭资源动作要完成
}
public static void demo_read() throws IOException{
    //创建一个读取流对象。和指定文件相关联
    FileInputStream fis = new FileInputStream("F:/buf.txt");
    System.out.println(fis.available());
    byte[] buf = new byte[fis.available()];
    fis.read(buf);
    System.out.println(new String(buf));//这个慎用
    //读数据建议使用这一种
    /*
    byte[] buf = new byte[1024];
    int len = 0;
    while((len=fis.read(buf))!=-1){
        System.out.println(new String(buf,0,len));
    }
    */
    /*
    int ch;//一次读取一个字节
    while((ch = fis.read())!=-1){
        System.out.print((char)ch);
    }
    */
}

字节流复制MP3

//字节流复制MP3
public static void demo_mp3() throws IOException{
    FileInputStream fis = new FileInputStream("F:/mp.avi");
    FileOutputStream fos = new FileOutputStream("F:/mp_copy.avi");
    /*
    byte[] buf = new byte[1024];
    int len = 0;
    while((len=fis.read(buf))!=-1){
        fos.write(buf,0,len);
    }
    */
    //千万别用下面这一种,效率太慢
    /*
    int ch;
    while((ch=fis.read())!=-1){
        fos.write(ch);
    }
    */
    fos.close();
    fis.close();
}
public static void demo_mp3_2() throws IOException{
    FileInputStream fis = new FileInputStream("F:/mp.avi");
    BufferedInputStream bufis = new BufferedInputStream(fis);
    FileOutputStream fos = new FileOutputStream("F:/mp_copy.avi");
    BufferedOutputStream bufos = new BufferedOutputStream(fos);
    byte[] buf = new byte[1024];
    int len = 0;
    while((len=bufis.read(buf))!=-1){
        bufos.write(buf,0,len);
        bufos.flush();
    }
    bufos.close();
    bufis.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值