IO流使用

32 阅读5分钟

一、IO流结构

IO流,大的分类分为字节流和字符流。字节流,传输的最小单位是字节,可以传输所有类型的文件;字符流,传输的最小单位是字符,在传输文本文件的场景中可以避免乱码问题。

使用IO中的任何一种实现类时,都是“三步走”,即 (1)创建流对象,关联文件 (2)读取/写入数据 (3)关闭流,释放资源 在这里插入图片描述

二、字节流使用

1、读取/写入:单个字节的读写

	// 1.创建流对象,关联文件
	FileInputStream fis = new FileInputStream("javaFile.txt");
	FileOutputStream fos = new FileOutputStream("javaFileOut.txt");
	
	// 2.1读取/写入一个字节,这里的read是可代表数据的码值,读取失败返回-1
	int read = fis.read();
	fos.write(read);
	
	// 3.关闭流,释放资源
	fis.close();
	fos.close();

在这里插入图片描述

2、使用循环,读取文件的所有内容

	// 1.创建流对象,关联文件
	FileInputStream fis = new FileInputStream("javaFile.txt");
	FileOutputStream fos = new FileOutputStream("javaFileOut.txt");
	
	// 2.2 使用循环,读取文件的所有内容,read = -1则说明数据读完了
	int read;
	while ((read = fis.read()) != -1){
	    fos.write(read);
	}
	
	// 3.关闭流,释放资源
	fis.close();
	fos.close();

在这里插入图片描述

3、设计一个字节数组,指定一次读取的大小,一般是1024Byte

需要注意的是,如果写入时没有设置限定范围,表示每次写入都是1024Byte,但如果最后一次读取不足于1024Byte,则会把上一次bytes数组中超出本次读取内容的部分,再写入到文件中。 这会导致写入的数据在末尾会有一小部分内容重复

	// 1.创建流对象,关联文件
	FileInputStream fis = new FileInputStream("javaFile.txt");
	FileOutputStream fos = new FileOutputStream("javaFileOut.txt");
	
	// 2.3 使用循环,读取文件的所有内容
	byte[] bytes = new byte[1024];
	int len;
	// 这里注意,fis.read()读取时需要加上字节数组;len返回的是fis.read()读取有效内容的字节数
	while ((len = fis.read(bytes)) != -1) {
	    // for.wirte()的三个参数,第一个是读取出来的字节数组,里面存储的是可代表数据内容的码值;后面两个是指写入bytes中的范围,指bytes[0-len)
	    fos.write(bytes, 0, len);
	}
	
	// 3.关闭流,释放资源
	fis.close();
	fos.close();

在这里插入图片描述

4、另外

(1)在创建输出流对象时,需要注意路径要写到“文件名”,不能写到目录级,否则会报“拒绝访问”的错误

	// 输出流对象的文件路径,要写到文件名级,不能写到目录级,会报错
	FileOutputStream fos = new FileOutputStream("superDir");

在这里插入图片描述

(2)输出流对象路径,没有文件会先创建一个新的空文件,如果已有文件,会清空文件内容。如果是追加操作,需要在创建对象时设置true

	//参数2,表示是否追加内容
	FileOutputStream fos = new FileOutputStream("javaFileOut.txt", true);

在这里插入图片描述 (3)在JDK1.7以后,凡实现了AutoCloseable接口的类,可以在try()小括号内创建流对象。这样程序结束后,会自动关闭流,不需要再手动关闭

	try (
	        // 1.创建流对象,关联文件(将流对象创建放在try()小括号内)
	        FileInputStream fis = new FileInputStream("javaFile.txt");
	        FileOutputStream fos = new FileOutputStream("javaFileOut.txt", true)
	) {
	
	    // 2.3 使用循环,读取文件的所有内容
	    byte[] bytes = new byte[1024];
	    int len;
	    while ((len = fis.read(bytes)) != -1) {
	        fos.write(bytes, 0, len);
	    }
	
	    // 3.不需要手动关闭流,这两行代码可去掉
	    //fis.close();
	    //fos.close();
	} catch (IOException e) {
	    e.printStackTrace();
	}

在这里插入图片描述

三、字符流使用

1、获取字符的码值

因为字节流传输的最小单位是字节,所以如果在读取/写入不全(3个字节表示一个汉字),或者读取和写入的字符集不同时(不统字符集表示字符的字节数不同),字符就会乱码。这时字符流的价值就体现出来了。

	String s = "我爱中国";
	
	// 使用getBytes()获取字符串的码值,这里使用的是UTF-8编码,三个码值表示一个字符,故输出9个码值
	byte[] bytes = s.getBytes();
	
	System.out.println(Arrays.toString(bytes));

2、使用字符流读取/写入数据

值得一说的是,字符流也可以像字节流那样读取/写入单个字符

	try (
	        // 1.创建流对象,关联文件
	        FileReader fr = new FileReader("javaFile.txt");
	        FileWriter fw = new FileWriter("javaFileOut.txt")
	) {
	
	    // 2.读取/写入
	    // 注意这里创建的是字符数组
	    char[] chars = new char[1024];
	    int len;
	    while (((len = fr.read(chars)) != -1)) {
	        // 用传入字符数组的方式创建字符串,注意需要限定有效的字符长度
	        String s = new String(chars, 0, len);
	        fw.write(s);
	    }
	
	    // 3.关闭流,释放资源,自动释放
	} catch (IOException e) {
	    e.printStackTrace();
	}

在这里插入图片描述

四、Buffered流

Buffered是一种自带缓存(8K)的高级流,IO的四种基本实现流,均有各自的Buffered流,在创建对应的Buffered时,需要传入基本实现流为参数。这里以字节流的Buffered为例,复制一个视频,测试Buffered流的效率

1.Buffered流使用,以字节流为例

	// 1.创建流对象,关联文件(Buffered流需要以基础流实现类对象为参数)
	BufferedInputStream bis = new BufferedInputStream(new FileInputStream("javaFile.txt"));
	BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("javaFileOut.txt"));
	
	// 2.读取/写入
	byte[] bytes = new byte[1024];
	int len;
	while (((len = bis.read(bytes)) != -1)) {
	    bos.write(bytes, 0, len);
	}
	
	// 3.关闭流,释放资源,手动关闭
	bis.close();
	bos.close();

在这里插入图片描述

2.用基础字节流和高速缓存流拷贝视频,对比效率

在这里插入图片描述

import java.io.*;

public class EssayTest3 {
    public static void main(String[] args) throws IOException {
        String inputPath = "C:\\Users\\10765\\Desktop\\Test\\video.mp4";
        String outBasicPath = "C:\\Users\\10765\\Desktop\\Test\\basic\\video.mp4";
        String outBufferedPath = "C:\\Users\\10765\\Desktop\\Test\\buffered\\video.mp4";

        System.out.println("基础字节流拷贝时长:" + basic(inputPath,outBasicPath) + "ms");
        System.out.println("高速缓存字节流拷贝时长:" + buffered(inputPath,outBufferedPath) + "ms");

    }

    public static long basic(String inputPath, String outPath) throws IOException {
        FileInputStream fis = new FileInputStream(inputPath);
        FileOutputStream fos = new FileOutputStream(outPath);

        long start = System.currentTimeMillis();

        byte[] bytes = new byte[1024];
        int len;
        while (((len = fis.read(bytes)) != -1)) {
            fos.write(bytes, 0, len);
        }

        fis.close();
        fos.close();

        long end = System.currentTimeMillis();

        return end - start;
    }


    public static long buffered(String inputPath, String outPath) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputPath));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(outPath));

        long start = System.currentTimeMillis();

        byte[] bytes = new byte[1024];
        int len;
        while (((len = bis.read(bytes)) != -1)) {
            bos.write(bytes, 0, len);
        }

        bis.close();
        bos.close();

        long end = System.currentTimeMillis();
        return end - start;
    }
}

在这里插入图片描述

首次发布

hezhongying.blog.csdn.net/article/det…