• 【Java】文件操作篇(二)字节输入流、字节输出流及常用子类


    💁 个人主页:黄小黄的博客主页
    ❤️ 支持我:👍 点赞 🌷 收藏 🤘关注
    🎏 格言:All miracles start from sometime somewhere, make it right now.
    本文来自专栏:JavaSE从入门到精通
    在这里插入图片描述

    写在前面

    🐱 较为完整的JavaIO流体系图如下:
    在这里插入图片描述
    本文涉及到InputStream字节输入流与OutputStream字符输出流常用的子类:

    1. FileInputStream:文件输入流;
    2. BufferedInputStream:缓存字节输入流;
    3. ObjectInputStream:对象字节输入流;
    4. FileOutputStream:文件输出流;
    5. BufferedOutputStream:缓存字符输出流;
    6. ObjectOutputStream:对象字符输出流。

    其中,对象字节输入流,将会与ObjectOutputStream一起讲解,敬请期待后续博文更新。


    1 FileInputStream文件输入流

    1.1 构造方法与常用方法摘要

    在这里插入图片描述

    🐦 方法摘要:
    在这里插入图片描述

    1.2 文件输入案例

    word.txt里存储了若干个单词,请你使用 FileInputStream 读取 word.txt 文件,并将文件内容显示到控制台。

    🐱 参考代码及结果:

    方式一:一个一个字节的读取

    import java.io.FileInputStream;
    import java.io.IOException;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     * 读取 word.txt案例演示
     */
    public class FileInputStreamTest1 {
        public static void main(String[] args){
            //1.创建FileInputStream对象
            String filePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\word.txt";
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(filePath);
                //2.read方法:读取单个字符,返回该字节码值,如果到达文件末尾,就返回-1
                //3.读取文件,并打印在控制台
                int readNum = 0;
                while ((readNum=fis.read()) != -1){
                    char readChar = (char)readNum;
                    if (readChar == '\n'){
                        System.out.println();
                    }else {
                        System.out.print(readChar);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //4.关闭文件流,释放资源
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    方式二:按照字节数组读取,提高效率

    import java.io.FileInputStream;
    import java.io.IOException;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     * 读取 word.txt案例演示
     */
    public class FileInputStreamTest1 {
        public static void main(String[] args){
            //1.创建FileInputStream对象
            String filePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\word.txt";
            int readLen = 0;
            //一次读取8个字节
            byte[] buf = new byte[8];
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(filePath);
                //2.从输入流读取最多 buf.length 字节的数据到字节数组
                //3.读取文件,并打印在控制台
                //读取正常,则返回实际读取的字节数,返回-1则读取完毕
                while ((readLen=fis.read(buf)) != -1){
                    String readString = new String(buf, 0, readLen);
                    if ("\n".equals(readString)){
                        System.out.println();
                    }else {
                        System.out.print(readString);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //4.关闭文件流,释放资源
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

    发现问题:

     在案例中,word.txt文件均是英文,如果包含汉字,则可能出现乱码。一般一个汉字按照3字节存储,但是按照字节方式去取值的时候,可能出现截断的情况, 比如,在某一次读取中只读了汉字3个字节中的1个字节,这就导致了乱码的情况。因此,Java提供了字符输入流,敬请期待下一篇博文。
    在这里插入图片描述


    2 FileOutputStream文件输出流

    2.1 构造方法与常用方法摘要

    在这里插入图片描述

    🐦 方法摘要:
    在这里插入图片描述

    2.2 文件输出案例

    使用FileOutputStream向wordtest.txt文件中输入一句话:Hello,world!

    🐱 参考代码及结果:

    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     */
    public class FileOutputStreamTest1 {
        public static void main(String[] args) {
            writeFile();
        }
    
        /**
         * 演示使用 FileOutputStream 将数据写入文件
         * 如果该文件不存在,则创建文件
         */
        public static void writeFile(){
            //创建 FileOutputStream 对象
            String filePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\wordtest.txt";
            FileOutputStream fos = null;
            try {
                //得到对象
                fos = new FileOutputStream(filePath);
                //写入字符串
                String str = "Hello, world!";
                fos.write(str.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    //释放资源
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    在这里插入图片描述

    🦁 说明:

    1. 案例中,是使用 new FileOutputStream(filePath) 创建方式,当写入内容时,会覆盖原来的内容;
    2. 如果不希望覆盖原来的内容,则应该采用追加的方式,将 append 参数设置为 true,即 new FileOutputStream(filePath,true);

    2.3 文件拷贝

    经过了对字节输入流与字节输出流的学习,下面尝试一下通过编程 实现对图片的拷贝操作。

    ⌨️ 参考代码及实现结果如下:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     */
    public class FileCopyTest {
        public static void main(String[] args) {
            String filePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\石原里美.jpg";
            String newFilePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\石原里美副本.jpg";
            boolean flag = copyFile(filePath, newFilePath);
            System.out.println("文件拷贝情况: " + flag);
        }
    
        /**
         * 拷贝文件的方法
         * @param filePath 旧文件路径
         * @param newFilePath 拷贝后文件存储路径
         * @return true代表拷贝成功, false代表拷贝失败
         */
        public static boolean copyFile(String filePath, String newFilePath){
            //1.创建文件输入流,将文件读入程序
            //2.创建文件输出流,将数据输出文件
            FileInputStream fileInputStream = null;
            FileOutputStream fileOutputStream = null;
    
            try {
                fileInputStream = new FileInputStream(filePath);
                fileOutputStream = new FileOutputStream(newFilePath, true);
                //3.定义一个数组,提高读取效果
                byte[] buff = new byte[1024];
                int readLen = 0;
                while ((readLen = fileInputStream.read(buff)) != -1){
                    //4.读取到后,就写入一部分,边读边写
                    //5.注意每次写入限制长度,否则,可能出现文件损失
                    fileOutputStream.write(buff, 0, readLen);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                try {
                    //6.释放资源
                    if (fileInputStream != null) {
                        fileInputStream.close();
                    }
                    if (fileOutputStream != null) {
                        fileOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
            }
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    可以看到,控制台显示文件拷贝成功,打开对应副本文件,图片显示正常。

    在这里插入图片描述
    在这里插入图片描述

    🐟 说明:

     在文件拷贝的时候需要特别注意,每次写入字节数组的时候需要限制大小,如果不进行限制,则会出现写入的数据量大于字节数组实际长度的情况,导致出现文件损失!

    在这里插入图片描述


    3 处理流

    3.1 BufferedInputStream介绍

    BufferedInputStream是字节流,在创建BufferedInputStream的时候,会创建一个内部缓冲区数组。

    在这里插入图片描述

    🐯 方法摘要:
    在这里插入图片描述

    3.2 BufferedOutputStream介绍

    该类实现缓冲输出流。 通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用。

    在这里插入图片描述

    🐰 方法摘要:
    在这里插入图片描述

    3.3 缓冲流拷贝图片

    与前面的案例一样,不同的是,这次我们使用字节缓冲流进行图片的拷贝!

    ⌨️ 参考代码:

    具体见注释:

    import java.io.*;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     * 字符缓存流复制文本文件演示
     */
    public class BufferedCopyTest {
        public static void main(String[] args) {
            String srcFilePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\石原里美.jpg";
            String destFilePath = "D:\\Ideaproject2021\\JavaSE\\src\\IOchapter\\石原里美副本(2).jpg";
            BufferedInputStream bufferedInputStream = null;
            BufferedOutputStream bufferedOutputStream = null;
            try {
                //创建流对象
                bufferedInputStream = new BufferedInputStream(new FileInputStream(srcFilePath));
                bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFilePath));
                //读取,边读边写
                byte[] buff = new byte[1024];
                int readLength = 0;
                while ((readLength = bufferedInputStream.read(buff)) != -1){
                    bufferedOutputStream.write(buff, 0, readLength);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                //释放资源
                try {
                    if (bufferedInputStream != null){
                        bufferedInputStream.close();
                    }
                    if (bufferedOutputStream != null){
                        bufferedOutputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    在这里插入图片描述


    写在最后

    🌟以上便是本文的全部内容啦,后续内容将会持续免费更新,如果文章对你有所帮助,麻烦动动小手点个赞 + 关注,非常感谢 ❤️ ❤️ ❤️ !
    如果有问题,欢迎私信或者评论区!
    在这里插入图片描述

    共勉:“你间歇性的努力和蒙混过日子,都是对之前努力的清零。”
    在这里插入图片描述

  • 相关阅读:
    Rust性能分析之测试及火焰图,附(lru,lfu,arc)测试
    08Maven中的继承和聚合的作用
    蓝桥杯2023年第十四届省赛真题-买瓜--C语言题解
    GO 工程下载依赖操作流程(go mod)
    Vue脚手架创建TS项目
    洛谷刷题C语言:Fergusonball Ratings、Don‘t Mozheng. /oh、gcd.、幻想乡扑克游戏、PMTD
    元组高级用法
    Hive 表 DML 操作——第2关:Select 操作
    uView实现全屏选项卡
    docker部署django(uwsgi+nginx)
  • 原文地址:https://blog.csdn.net/m0_60353039/article/details/126775293