IO流总结

一、什么是流

流通常可以理解外一串连续不断的数据的集合,就像你家的水龙头,水的一端是水泵在一点一点的供水,而在另外一端看到的是一股连续不断的水流。数据的写入可以是一段一段向管道中写入数据,这些数据段,会先后排成一个长长的数据流。对于数据读取程序来说,看不到流写入时的情况,每次读取只能先读取前面先到达的数据,再读取后面的数据。就好像水龙头,你只有放掉了水管前面的水,才能收到水管后面的水。

二、IO流的分类

(1)按照读取类型可以分为:

  • 字节流
  • 字符流

(2)按照读取方向可以分为:

  • 输入流
  • 输出流
三、IO继承关系图(部分)

在这里插入图片描述

四、字符流
(1)FileReader

FileReader用于读取字符文件。

public class ReadFile {
    public static void main(String[] args) throws Exception {
        /**
         * int  read(char cbuf[])方法 将读取的字符数 存储在cbuff的char数组中
         * 返回值:位读取字符的长度
         * 如果读到最后了 返回-1
         */
        int len = 0;
        char [] temp = new char[1024];
        Reader reader = new FileReader(new File("D:\\testfile\\a.txt"));
        while ((len=reader.read(temp))>0){
            System.out.println(new String(temp,0,temp.length));
        }
       //关流
        reader.close();
        }
}
(2)FileWriter

FileWriter用于输出字符流,将字符流写入文件

// 将字符串写出到a.txt文件
public class WriterFile {
    public static void main(String[] args) throws Exception {
        FileWriter fileWriter = new FileWriter(new File("D:\\testfile\\a.txt"));
        fileWriter.write("我来写出字符串");
        //刷新 写入
        fileWriter.flush();
        //关流
        fileWriter.close();
    }
}
复制文本

将一个文本内容 复制到另外一个文件中

/**
 * @author hao
 * @create 2019-07-27 ${TIM}
 * 复制字符流
 * 将a.txt的文本内容复制到b.txt中
 */
public class CopyFile {
    public static void main(String[] args) throws Exception{
        int len = 0;
        char [] temp = new char[1024];
        //声明字符读取流b
        Reader reader = new FileReader(new File("D:\\testfile\\a.txt"));
        //字符输出流
        FileWriter fileWriter = new FileWriter(new File("D:\\testfile\\b.txt"));
        while ((len=reader.read(temp))>0){
            fileWriter.write(temp,0,len);
            //每次都要刷新写入
            fileWriter.flush();
        }
        //关闭资源
        fileWriter.close();
        reader.close();
    }
}
(3)字符缓冲流

1、BufferedWriter
BufferedWriter,使用缓冲区功能写出字符。他的构造函数BufferedWriter(Writer out) 传入一个字符输入流,其实这是属于一种装饰者模式,对传入的Writer进行加强了。
通过BufferedWriter源码发现
1、当使用write(char cbuf[], int off, int len)会自动调用刷新flushBuffer()
2、BufferedWriter有一个独有的方法 newLine() 产生一个新行

public class BufferedWriterFile {
    public static void main(String[] args) throws Exception{
        //构建字符缓冲区输出流
        //他的构造函数BufferedWriter(Writer out) 传入一个字符输入流
        //BufferedWriter特点:
        //1、当使用write(char cbuf[], int off, int len)会自动调用刷新
        //2、 close()方法的时候 会执行刷新动作
        BufferedWriter writer = new BufferedWriter(new FileWriter(new File("D:\\testfile\\a.txt")));
        writer.write("哈哈哈哈或");
        writer.write("嘿嘿嘿嘿");
        writer.write("喵喵喵喵");
        
        //关闭资源(内部进行了刷新缓冲区)
        writer.close();
    }
}

当我们以上面的方法,写出时,我们的内容都会是一行的 ,如下:

哈哈哈哈或嘿嘿嘿嘿喵喵喵喵

可以是用两种方式使得换行,1.在结尾加上换行字符\n 2.使用newLine()产生新的一行再写出

	    writer.write("哈哈哈哈或");
        writer.newLine(); //产生新的一行
        writer.write("嘿嘿嘿嘿");
        writer.newLine();
        writer.write("嘿嘿嘿嘿");
        writer.newLine();
        writer.write("喵喵喵喵");

其实内部也是写入一个\n只不过这种方法更加优雅。
2、BufferedReader
BufferedReader字符缓冲读取流:从一个字符输入流中读取文本。缓冲字符,以便提供字符、数组和行的有效读取。

public class BufferedReaderFile {
    public static void main(String[] args) throws Exception {
        BufferedReader readerFile = new BufferedReader(new FileReader(new File("D:\\testfile\\a.txt")));
        /** 
         * 使用readLine()每次读取一行 当有数据时候 返回读取到行内容  当没有数据的时候 返回null 
         */String len = null;
        while ((len=readerFile.readLine())!=null){
            System.out.println(len);
        }
        readerFile.close();
    }
}


五、字节流

字节流,以字节为单位,读取文件,输出文件
(1)InputStream:字节输入流。


/**
 * @author hao
 * @create 2019-07-27 ${TIM}
 * 以字节流的形式读取
 * 读取c.txt中的数据
 * c.txt中的内容 只有一个字符 A
 */
public class InputStreamFile {
    public static void main(String[] args) throws IOException {
        //获得流
        InputStream inputStream = new FileInputStream(new File("D:\\testfile\\c.txt"));
        //将获得流的byte 存储在int中
        int read = inputStream.read();
        System.out.println(read);//输出结果65
    }
}

输出结果:65
说明,是以字节为单位读取的文件。一个字母A,占一个字节。每次读取一个字节

(2)OutputStream 字节输出流

public class OutputStreamFile {
    public static void main(String[] args) throws Exception{
        //获得流
        OutputStream outputStream = new FileOutputStream(new File("D:\\testfile\\c.txt"));
        //字节数组输出
        outputStream.write("hello".getBytes());
        //关闭流
        outputStream.close();
    }
}

·(3)复制操作
概述:将一个文件以字节流的形式读入,再以流的形式写出,从而达到复制的目的。因为是字节流,理论上可以复制所有类型的文件。测试复制一个音频文件。

public class CopyFile {
    public static void main(String[] args) {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            long start = System.currentTimeMillis();
            in = new FileInputStream("D:\\testfile\\a\\海阔天空.mp3");
            out = new FileOutputStream("D:\\testfile\\b\\海阔天空.mp3");
            //临时缓存字节
            byte [] temp = new byte[1024];
            int len = 0;
            while ((len =in.read(temp))!=-1){
                //进行写出
                out.write(temp,0,len);
            }
            long end = System.currentTimeMillis();
            System.out.println("复制花费时间: "+(end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null!=in)in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null!=out)out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
输出:复制花费时间: 170

(4)缓冲流
设置缓冲区,可以加快读流和写流的速度
BufferedInputStream ,BufferedOutputStream,分别是输入缓冲流和输出缓冲流。通如下过构造方法,获得对象。
使用读取和写出的方法相同。其实就是加强版的InputStreamOutputStream

  public BufferedInputStream(InputStream in)
  public BufferedOutputStream(OutputStream out)

同样的复制操作使用,缓冲流

public class CopyFile {
    public static void main(String[] args) {
        BufferedInputStream in = null;
        BufferedOutputStream out = null;

        try {
            long start = System.currentTimeMillis();
            in = new BufferedInputStream(new FileInputStream("D:\\testfile\\a\\海阔天空.mp3"));
            out = new BufferedOutputStream(new FileOutputStream("D:\\testfile\\b\\海阔天空.mp3"));
            //临时缓存字节
            byte [] temp = new byte[1024];
            int len = 0;
            while ((len =in.read(temp))!=-1){
                //进行写出
                out.write(temp,0,len);
            }
            long end = System.currentTimeMillis();
            System.out.println("复制花费时间: "+(end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null!=in)in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(null!=out)out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
输出:复制花费时间: 120

通过对比发现使用缓冲流的复制时间小于未使用的。说明可以提高效率。

六、转换流

(1)InputStreamReader 是字节转字符的输入流。他是字节流通向字符流的桥梁:它使用chartset读取字节,并将其解码。(如果未设置,将使用默认的编码格式)

//构造方法
//传入一个 字节流 并制定编码格式
  public InputStreamReader(InputStream in, Charset cs)

InputStreamReader代码:

public class InputStreamReaderFile {
    public static void main(String[] args) throws Exception {
    	//使用GBK方式 读取字节流 并将其解码
        InputStreamReader reader = new InputStreamReader(new FileInputStream("D:\\testfile\\b1.txt"),"GBK");
        int len = 0;
        char [] temp = new char[1024]; while ((len=reader.read(temp))>0){
            System.out.println(new String(temp,0,temp.length));
        }
        reader.close();
    }
}

(2)OutputStreamWriter:是字节转字符流的桥梁:他使用制定的charst将字节转换为字符并且写入。

public class OutputStreamWriterFile {
    public static void main(String[] args ) throws Exception {
        FileOutputStream fos=new FileOutputStream("d:\\testfile\\a.txt");
        //以gbk编码格式写出  这就要求写入的文件必须是以gbk编码的
        OutputStreamWriter opsw=new OutputStreamWriter(fos,"GBK");
        opsw.write("我好你好大家好");
        opsw.close();
    }
}

(3)练习情景
将一个以gbk编码的a.txt内容 复制到 以utf-8编码的b.txt 这个时候就需要用到转换流啦

    @Test
    public void test() throws Exception{
        InputStreamReader reader = new InputStreamReader(new FileInputStream("D:\\testfile\\a.txt"),"GBK");
        OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream("d:\\testfile\\b.txt"),"UTF-8");
        int len = 0;
        char [] temp = new char[1024];
        while ((len=reader.read(temp))>0){
            writer.write(temp,0,len);
        }
        //关流
        reader.close();
        writer.close();
    }

其实我们看继承树就可以发现,FileWriter是OutputStreamWriter的子类,FileReaderOutputStreamWriter子类。而且他们底层也是调用他们父类方法实现的。
当我们调用FileWriter的构造方法的时候,调用父类的构造

    public FileWriter(File file) throws IOException {
    //它是调用他的父类,其实也就是OutputStreamWriter
        super(new FileOutputStream(file));
    }
    

父类的构造

    public OutputStreamWriter(OutputStream out) {
        super(out);
        try {
            se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
        } catch (UnsupportedEncodingException e) {
            throw new Error(e);
        }
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值