IO流(五):字节流-输入流(Inpustream)、输出流(OutputStream)--使用场景、弊端、注意事项、代码演示。

目录

1、什么是字节流?

2、字节输入流--FileInputStream

2.1 int read()方式代码演示以及注释

2.1.1 读取一个字节

2.1.2 将整个文件挨个字节读取并打印演示

2.2 int read(byte[] buffer)方式代码演示以及注释

2.2 .1 一次读取3字节演示

2.2.2 一次性读取全部数据演示

3、输出流-FileOutputStream

3.1 写一个字节出去演示

3.2 批量写字节出去

4、总结


1、什么是字节流?

就是以字节为单位传输数据的管道、分为输入字节流和输出字节流

对流的概念不了解的同学可以看我上一篇发布的文章,很详细,链接我放下面了:

IO流(四):IO流的概述,分类,输入流输出流(input、output),字节流字符流、程序怎么读取文件概述-CSDN博客

2、字节输入流--FileInputStream

FileInputStream读取数据有2种方式,我们把数据比作水

int read() : 一个一个字节读取,一滴水一滴水获取

int read(byte buffer) :批量读取字节,buffer相当于一个水桶的大小,去一桶一桶把水装回来

2.1 int read()方式代码演示以及注释

这是我建的一个文件,下面演示如何读取这个文件

2.1.1 读取一个字节

public class FileInputStreamTest1 {

    public static void main(String[] args) {
        InputStream inputStream = null;
        try {
            //创建文件字节输入流管道,与文件接通
            inputStream = new FileInputStream("src\\main\\resources\\bbb.txt");
            try {
                int read = inputStream.read(); //每次读取一个字节返回(注意:取回来的是一个字节,因为字节比int小,所以拿int来接这个字节)
                System.out.println((char)read); //将读出来的字节转为字符类型
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

我们可以看到读取到第一个字节为j


2.1.2 将整个文件挨个字节读取并打印演示

如果没有数据了就会返回-1,表示读取文件结束。

public class FileInputStreamTest1 {

    public static void main(String[] args) {
        InputStream inputStream = null;
        try {
            //创建文件字节输入流管道,与文件接通
            inputStream = new FileInputStream("src\\main\\resources\\bbb.txt");
            try {
                int read;
                while ((read = inputStream.read()) != -1){  //当读取到的字节为空时,返回-1,表示读取文件结束
                    System.out.print((char)read); //将读出来的字节转为字符类型
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

我们可以看到,我们将整个文件都读取出来并且打印了

弊端一:读取数据的性能很差,每读取一个字符就要去硬盘中拿一次。

程序在内存中执行,不能直接找硬盘文件。程序是通过调用系统里的硬件资源去读取硬盘文件里的数据的,程序调用系统里的硬件资源开销以及去硬盘中找到对应文件数据的性能开销,相对内存是很慢的

弊端二:不能读取中文,会乱码

由于在UTF-8中我们一个中文字符是占用三个字节的,int read()的方式又是一个一个字节读取的,所以就会出现乱码的情况

所以我们下面介绍第二种方法 int read(byte[] buffer),一次读取多个数据,减少程序调用系统硬件资源的次数。
如果是一次性全部读取数据,可以解决中文乱码的情况,但是需要注意的是,我们的内存是远远小于硬盘的,如果需要读取的文件过大,会把我们的内存撑爆。

2.2 int read(byte[] buffer)方式代码演示以及注释

buffer的大小我们可以自己定义,最好是一次性就能把文件中的数据读过来(理想情况),这样的话只需要调用硬件资源一次。

2.2 .1 一次读取3字节演示

public class FileInputStreamTest2 {
    public static void main(String[] args) {
        InputStream inputStream = null;
        try {
            //创建文件字节输入流管道,与文件接通
            inputStream = new FileInputStream("src\\main\\resources\\bbb.txt");
            try {
                byte[] buffer = new byte[3];  //将桶的大小定义为3,一次性读取3个字节
                int len = inputStream.read(buffer); //实际上读出来的数据,因为你可能会有装不满的情况
                //现在桶里面以及有数据了,我们将桶里面的数据转为字符串,这个写法表示读出来多少倒出来多少
                String result = new String(buffer,0,len);
                System.out.print(result);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

可以看到我们一次性读取了3个字节,减少了程序调用硬件资源的次数,提高性能        

2.2.2 一次性读取全部数据演示

public class FileInputStreamTest2 {
    public static void main(String[] args) {
        InputStream inputStream = null;
        try {
            //创建文件字节输入流管道,与文件接通
            inputStream = new FileInputStream("src\\main\\resources\\bbb.txt");
            try {
                byte[] bytes = inputStream.readAllBytes();//将所有的字节全部读取
                String result = new String(bytes);
                System.out.print(result);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

可以看到,我们一次性就把文本中的数据读取过来了

3、输出流-FileOutputStream

3.1 写一个字节出去演示

注意创建管道时的追加参数设置,默认为false是会替换原来的文本的

public class FileOutputStreamTest1 {
    public static void main(String[] args) {
        OutputStream outputStream = null;
        try {
            //创建文件字节输出流管道,与文件接通
            //该文件不需要我们手动创建
            // 这个true表示追加数据,默认为false,即替换原来的数据
            outputStream = new FileOutputStream("src\\main\\resources\\outputTest.txt",true); 
            try {
                outputStream.write('a'); //将一个字节写到我们的文件中
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                outputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

我们可以看到,系统自动给我们创建了一个目录并且把字节写进去 

3.2 批量写字节出去

public class FileOutputStreamTest1 {
    public static void main(String[] args) {
        OutputStream outputStream = null;
        try {
            //创建文件字节输出流管道,与文件接通
            //该文件不需要我们手动创建
            // 这个true表示追加数据,默认为false,即替换原来的数据
            outputStream = new FileOutputStream("src\\main\\resources\\outputTest.txt",true);
            try {
                byte[] bytes = "柔弱女子爱java".getBytes();
                outputStream.write(bytes); //将"柔弱女子爱java"这个字符串转为字节写到文件中
                outputStream.write("\r\n".getBytes()); //将换行符转为字节写到文件中,这种写法能在多种平台兼容,例如window,linux
                byte[] byte2 = "努力学习中".getBytes();
                outputStream.write(byte2); //将"努力学习中"这个字符串转为字节写到文件中
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                outputStream.close();  //关闭流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

4、总结

int read() 读取数据的性能很差,每次只读取一个字节,正因如此,所以读取汉字会乱码(汉字在UTF-8中国占用3字节,一次读取一个字节相当于把字节拆开了解码,就会出现乱码)。

想要解决以上两种情况,就需要用到  int read(byte[] buffer),如果一次性能全部把文件数据读取出来,即能解决重复调用硬件资源问题,又能解决中文乱码的情况的(需要注意文件内容过大,内容溢出的情况)。

使用完流之后,记得要关闭流。流的底层是要和系统资源关联的,是要通过调用系统资源来读取文件里面的数据,所以流用完之后,应该通知系统资源关闭,不再占用系统资源,即关闭IO流,可以提高性能。

注意:实际应用开发中,虽然字节流能操作图片、文本、视频等,但是更加适用于文本拷贝或者数据备份的业务,读取文本更适合字符流(之后会更新这一部分)。

使用字节流拷贝照片的案例链接我放下面啦:

IO流实用案例:用字节流--输入流(Inpustream)、输出流(OutputStream)写一个拷贝图片的案例--超简单!-CSDN博客

这就是我对字节流的理解,希望能帮到大家,有问题的地方欢迎大家一起讨论!

后续会不断更新作品,欢迎大家一起讨论学习。❤❤❤

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值