黑马程序员——JAVA笔记之IO流(一)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

IO流(一)

IO流按照操作数据分为两种:分为字符流和字节流。
按照流向分类分为:输入流和输出流。
字符流通用字节流,字符流是为了防止文件传递之间产生的乱码。所以,一般如果文件是纯文本格式,就用字符流,如果不是就用字节流。
其字节流的抽象基类为:InputStream, OutputStream.
字符流的抽象基类为:Reader, Writer.
这四个类型派生出的子类都是“xxx父类名”。如:InputStream的子类就是FileInputStream。Reader的子类就是FileReader。

这里写图片描述

一、字符流
Reader:用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。
Writer:写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。

IO异常的处理方式:

public class FileWriterDemo{
    public static void main(String[] args) {//throws IOException{
        FileWriter fw = null;   //为防止fw.close访问不到。在外面建立引用
        try{
            fw = new FileWriter("444.txt");//在try内进行初始化
            fw.write("asdifj");
            //fw.flush();
            //fw.close();   //close还有异常,需要finally
        }
        catch(IOException e){           
            System.out.println(e.toString());
        }
        finally{
            try{
                if(fw!=null)//初始化没有成功的化,close会异常。
                    fw.close();
            }
            catch(IOException e){
                System.out.println(e.toString());
            }

        }
    }
}

通常数组空间定义为1024的整数倍。
将一个文件拷贝到另一个文件中:

package test;

import java.io.*;

public class FileReaderDemo{
    public static void main(String[] args){
        copy();
    }

    public static void copy(){
        FileWriter fw= null;
        FileReader fr= null;
        try {
            fw = new FileWriter("11.txt");
            fr = new FileReader("CalendarDemo.java");

            char[] buf= new char[1024];
            int len=0;

            while ((len=fr.read(buf))!=-1) {//将原文件中的数据整到数组中,数组长度为len。
                fw.write(buf, 0, len);//将流中的数据写入流中
            }
        } catch (IOException e) {
            // TODO: handle exception
            throw new RuntimeException("读取错误!");//抛出异常。
        }finally{
            if (fw!=null)
                try {
                    fw.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    if (fr!=null) {
                        try {
                            fr.close();
                        } catch (Exception e2) {
                            // TODO: handle exception
                        }
                    }
                }


        }
    }
}

二、缓冲区
缓冲区要结合流才可以使用。是在流的基础上对流的功能进行了增强。缓冲区的出现是为了提高流的操作效率出现的,所以创建缓冲区之前,必须要先有流对象。
改缓冲区中提供了一个跨平台的换号符:newLine();
BufferedWriter:是给字符输出流提高效率用的,那就意味着,缓冲区对象建立时,必须要先有流对象。明确要提高具体的流对象的效率。
使用缓冲区写一个文件存到另一个文件中代码:

package test;

import java.io.*;

public class BufferedReaderDemo {
    public static void main(String[] args) //throws IOException
    {
        BufferedReader bufr= null;
        BufferedWriter bufw= null;
        try{
            bufr = new BufferedReader(new FileReader("21.txt"));
            bufw = new BufferedWriter(new FileWriter("23.txt"));

            String line =null;
            while((line= bufr.readLine())!=null){// readLine方法返回的时候是不带换行符
                bufw.write(line);
                bufw.newLine();
                bufw.flush();
            }


        }catch(IOException e){
            throw new RuntimeException("读取错误!");
        }
        finally{
        try {
            if(bufr!=null)
            bufr.close();
            if(bufw!=null);
            bufw.close();
        } catch (Exception e2) {
            // TODO: handle exception
        }

        }
    }
}

三、装饰设计模式
当想要对已有的对象进行公告增强时,可以定义类,将已有的对象转入,基于已有的功能,并提供加强功能。这个定义的类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
BufferedReader也是装饰设计的一种。

该模式和继承有什么区别呢?
它比继承有更好的灵活性。避免了基础体系的臃肿。而且降低了类与类之间的关系。通常装饰类和被装饰类都同属与一个父类或者接口。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类同事是都属于一个体系中的。
为提高扩展性,将扩展子类结合。
举例说明就是:
定义一个MyReader专门用于读取数据的类。
|–MyTextReader
|–MyBufferedTextReader
|–MyMediaReader
|–MyBufferedMediaReader
|–MyDataReader
|–MyBufferedDataReader

转换为
|–MyTextReader
|–MyMediaReader
|–MyDataReader
|–MyBufferedReader

class MyBufferedReader extends MyReader{
    private MyReader r;
    MyBufferedReader(MyReader r){
    }
}

四、字节流

InputStream:是表示字节输入流的所有类的超类。是读。
OutputStream:此抽象类是表示输出字节流的所有类的超类。是写。
available();可以定义一个刚刚好的缓冲区,不用在循环读取了。

public static void readFile_3() throws IOException{
        FileInputStream fis= new fileInputSream("23.txt");
        byte[] buf = new byte[fis.available()];
        fis.read(buf);
        System.out.println(new String(buf));
        fis.close();
}

但是如果数据太大的话,会造成内存溢出,所以此方法慎用。最优化的还是定义byte[1024],最优化。

复制MP3代码:

package test;

import java.io.*;

public class copyMP3{
    public static void main(String[] args){
        BufferedInputStream bufis = null;
        BufferedOutputStream bufos = null;
        try{
            bufis= new BufferedInputStream(new FileInputStream("a.mp3"));
            bufos= new BufferedOutputStream(new FileOutputStream("b.mp3"));

//          byte[] buf= new byte[1024*5];//不用定义数组,因为Buffered缓冲区本身就是一个数组等同于一个数组缓存到另一个数组当中去,若用的话会造成文件传输变大.若要使用需要by=bufis.read(buf, 0, by);读取冲0到by长度的。
            int by= 0;

            while((by=bufis.read())!=-1){
                bufos.write(by);
            }
        }
        catch(IOException e){
            System.out.println("dqcw");
        }
        finally{
            try{
                bufis.close();
                bufos.close();
            }
            catch(IOException e){
            }   
        }
    }
}

字符流的缓冲区一般是不用字节数组的,会造成文件传输变大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值