Java学习【IO流:深入理解与应用(上)】

news2024/12/25 14:58:19

Java学习【IO流:深入理解与应用(上)】

  • 🍃1.IO流体系结构
  • 🍃2.FileOutputStream
    • 🍁2.1FileOutputStream写数据的三种方式
    • 🍁2.2换行和续写
  • 🍃3.FileInputStream
    • 🍁3.1每次读取一个字节
    • 🍁3.2读取多个字节
  • 🍃文件拷贝
  • 🍃IO流中的异常处理方式

在这里插入图片描述
🚀所属专栏:Java学习⭐⭐
🚀欢迎互三👉: 2的n次方_⭐⭐

🍃1.IO流体系结构

在Java编程中,IO(Input/Output)流是一个非常重要的概念,它允许我们与各种数据源(如文件、网络、内存等)进行交互。Java的IO库提供了丰富的类和方法,用于读取和写入数据。

IO流按照操作文件类型又可以分为
字节流:可以操作所有类型文件
字符流:只能操作纯文本文件
在这里插入图片描述
由于上面的四个都是抽象类,在实现的时候要创建子类的对象,这里以字节流为例,下面是其两个子类
在这里插入图片描述

🍃2.FileOutputStream

FileOutputStream:操作本地文件的字节输出流,可以把程序中的数据写入到本地文件中。

1.参数是字符串表示的路径或者File对象都可以
2.如果文件不存在就会创建一个新的文件,但是要保证父级路径是存在的
3.如果文件存在,那么会清空文件中的数据,然后再写入
写入文件时,传入参数是整数,会转换为ASCII码对应的字符
如果想要写入整型,就分开写对应的ASCII码

🍁2.1FileOutputStream写数据的三种方式

在这里插入图片描述

创建对象之后是通过调用write()方法进行写入

FileOutputStream fos = new FileOutputStream("E:\\java\\a.txt");
        // 写入一个数据
        fos.write(97);

这里会出现异常,将异常进行抛出处理
在这里插入图片描述
write()也提供了其他的重载方法
在这里插入图片描述

可以传入一个byte类型的数组,写入多个字节,还可以指定写入的起始索引,再指出写入几个字节

        byte[] bytes = {97, 98, 99, 100};
        fos.write(bytes);
        //从1索引开始写入两个字符
        fos.write(bytes, 1, 2);

每次执行操作结束之后都要调用close()方法进行资源释放,否则文件就会一直被占用
在这里插入图片描述

public class ByteStreamDemo1 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("E:\\java\\a.txt");
        // 写入一个数据
        fos.write(97);
		//写入多个数据
        byte[] bytes = {97, 98, 99, 100};
        fos.write(bytes);
        //从1索引开始写入两个字符
        fos.write(bytes, 1, 2);
        //释放资源,解除资源占用
        fos.close();
    }
}

🍁2.2换行和续写

除了以上三种写入方式外,还可以通过字符串的方式进行写入
此外,如果需要写入换行,在windows操作系统中,是用 “\r\n” 表示换行

public class ByteStreamDemo1 {
    public static void main(String[] args) throws IOException {

        FileOutputStream fos = new FileOutputStream("E:\\java\\a.txt");
        //写入字符串
        String str = "hello";
        byte[] bytes1 = str.getBytes();
        fos.write(bytes1);
        //写入换行
        String s = "\r\n";
        fos.write(s.getBytes());
        fos.write(97);
        //释放资源,解除资源占用
        fos.close();
    }
}

打开记事本查看a.txt的内容
在这里插入图片描述
续写就是不清空原来文件的内容,接着往下写
FileOutputStream()的构造方法还有一个boolean类型的参数,表示续写开关,默认是false,如果创建对象时给出true,那么就表示续写,此时就不会清空原来文件的内容
在这里插入图片描述

public class ByteStreamDemo1 {
    public static void main(String[] args) throws IOException {
        //续写,之前内容不会清空
        FileOutputStream fos1 = new FileOutputStream("E:\\java\\a.txt", true);//打开续写
        fos1.write("666".getBytes());
        //释放资源
        fos1.close();
    }
}

可以看出,这次是接着上次的内容继续进行写入的
在这里插入图片描述

🍃3.FileInputStream

操作本地文件的字节输入流,可以把本地文件中的数据读取到程序中来

🍁3.1每次读取一个字节

在这里插入图片描述

第一步也是创建对象,接着调用read()方法,就可以读取到一个字节的内容,读到的内容也是ASCII码对应的数字

public class ByteStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //字节输出入流,如果文件不存在,就会报错
        FileInputStream fis = new FileInputStream("E:\\java\\a.txt");
        //读取一个字节,读取到末尾再继续读会返回-1
        int res = fis.read();
        System.out.println((char) res);
        //释放资源
        fis.close();
    }
}

在这里插入图片描述
创建对象时,如果对应路径不存在,就会直接报错,此外,读取到末尾之后继续读就会返回-1,那么文件中最后确实是-1的话怎么判断呢?“-1"其实是分为”-" 和 "1"的,所以并不冲突
根据这个特性可以进行文件的循环读取

		int a = 0;
        while ((a = fis.read() )!= -1){
            System.out.print((char)a);
        }
        System.out.println();

问题:如果不用一个变量来接收行不行?

        while(fis.read() != -1){
            System.out.println((char)fis.read());
        }

答:因为每次调用read就表示往后移动一位,所以每次循环都进行了两次读取(判断条件一次,输出语句一次),打印的数据其实是跳跃的

🍁3.2读取多个字节

如果要读取多个字节,可以在read方法中传入一个byte类型的数组,数组长度是多少每次就读几个字节

public class ByteStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //字节输出入流,如果文件不存在,就会报错
        FileInputStream fis = new FileInputStream("E:\\java\\a.txt");
        //读取多个字节
        byte[] byte1 = new byte[3];
        int len1 = fis.read(byte1);
        System.out.println(new String(byte1));
        System.out.println(len1);

        //如果继续往下读,因为文件中剩余的数据不足数组的长度,只覆盖读取到了的数据
        int len2 = fis.read(byte1);
        System.out.println(new String(byte1));
        System.out.println(new String(byte1,0,len2));//只打印读到的数据
        System.out.println(len2);
        //释放资源
        fis.close();
    }
}

如果继续往下读,文件中剩余的数据不足数组的长度,只覆盖读取到的数据,此时就可以把读取的字节数进行一个返回,只打印读取到的数据,也就是没有被覆盖的数据不打印
在这里插入图片描述

🍃文件拷贝

文件拷贝就是把读取和写入结合起来,把读取到的数据再写入另一个文件中,所以也有两种方式进行拷贝,一种是一个字节一个字节的拷贝,另一种就是直接定义一个大容量的数组,一次拷贝完成,很显然,后者更加高效

public class ByteStreamDemo3 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("E:\\java\\a.txt");
        FileOutputStream fos = new FileOutputStream("E:\\java\\b.txt");

        //一次拷贝一个字节
        int b1 = 0;
        while ((b1 = fis.read()) != -1) {
            fos.write(b1);
        }

        //一次拷贝多个字节
        byte[] b2 = new byte[1024];
        int len = 0;
        while((len = fis.read(b2)) != -1){
            fos.write(b2,0,len);
        }
        //释放资源,先开后关
        fos.close();
        fis.close();
    }
}

最后释放资源的时候需要注意,遵循最先打开的文件最后关闭的原则

🍃IO流中的异常处理方式

在之前,我们都是对异常进行抛出处理,怎么去使用try - catch处理呢?
首先需要明白,程序最后都要进行资源释放,所以就可以采用try - catch - finally结构,把资源释放的模块放在finally里
在这里插入图片描述
如果按照正常的想法,把有异常的模块都放进try里,此时创建出的对象就属于局部变量,finally里调用不了,就需要把创建对象的部分写在外面
在这里插入图片描述
但此时还是报错了,还需要对finally的内容进行异常处理
在这里插入图片描述
这样看貌似是没有问题了,但是还是有一个细节需要注意,如果创建对象时给的路径不存在,还是会报错,除了正常给出的路径异常,还有一个空指针异常
在这里插入图片描述
就需要处理对象为空的情况

public class ByteStreamDemo4 {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("E:\\java\\a.txt");
            fos = new FileOutputStream("E:\\java\\b.txt");
            //一次拷贝多个字节
            byte[] b = new byte[1024];
            int len = 0;
            while ((len = fis.read(b)) != -1) {
                fos.write(b, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源,先开后关
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

此时再运行就没有空指针异常了
上面的代码看起来很多,在JDK7和JDK9种给出了两种简化版本,推出了AutoCloseable接口,它定义了一个可以被自动关闭的资源,确保在 try 代码块执行完毕后,资源能够自动关闭,即使发生了异常,但是只能在特定的情况可以使用
JDK7:
在这里插入图片描述
JDK9:
在这里插入图片描述
这样就不用在finally种写一堆对释放资源处理的异常了,不过,一般情况下直接抛出就可以了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1876693.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑文件kernel32.dll缺失要怎么处理?怎么才能一键修复kernel32.dll文件

关键系统文件kernel32.dll的缺失,这种情况不仅会导致系统运行不稳定,甚至可能完全无法启动某些应用程序。kernel32.dll 是一个至关重要的动态链接库文件,它与Windows操作系统的多个基本操作相关联,包括内存管理、进程和线程的控制…

java热部署idea插件「jrebel安装教程」

告别漫长的项目重启等待,让开发像写诗一样流畅~ jrebel安装包下载 jrebel版本需要下比较老的版本,我用的是22.4.1的版本(如果不差钱,可以支持一下正版,直接选择最新的版本即可) 下载地址:传送门…

.NET周刊【6月第4期 2024-06-23】

国内文章 C#.Net筑基-集合知识全解 https://www.cnblogs.com/anding/p/18229596 .Net中提供了数组、列表、字典等多种集合类型,分为泛型和非泛型集合。泛型集合具有更好的性能和类型安全性。集合的基础接口包括IEnumerator、IEnumerable、ICollection、IList、ID…

WPF UI交互专题 界面结构化处理 查看分析工具Snoopy 逻辑树与视觉树 平面图像 平面图形 几何图形 弧线 01

1、开发学习环境 2、XAML界面结构化处理 3、逻辑树与视觉树 4、基于XAML的标签扩展方式 5、基础控件应用分析 6、控件常用属性与事件总结 7、常用控件特别属性说明 8、平面图形控件与属性 9、平面几何图形 10、弧线的处理过程 WPF项目-XAML 项目表现形式 项目结…

HarmonyOS APP应用开发项目- MCA助手(持续更新中~)

简言: gitee地址:https://gitee.com/whltaoin_admin/money-controller-app.git端云一体化开发在线文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/agc-harmonyos-clouddev-view-0000001700053733-V5 注&#xff1…

揭示隐藏的模式:秩和检验和单因素方差分析的实战指南【考题】

1.研究一种新方法对于某实验结果准确性提高的效果,并将其与原有方法进行比较,结果见下表,请评价两者是否有不同? (行无序,列有序)-->单方向有序-->两独立样本的秩和检验) 如下图所示,先将相关数据导入spss。 图…

武汉星起航:一站式服务,助力亚马逊卖家高效运营,实现收益飞跃

在跨境电商的浪潮中,武汉星起航电子商务有限公司以其独特的一站式跨境电商服务,为众多亚马逊卖家提供了强有力的支持,助力他们在不断发展的市场中脱颖而出,实现收益的大幅提升。 武汉星起航的一站式跨境电商服务,以其…

Linux /proc目录总结

1、概念 在Linux系统中,/proc目录是一个特殊的文件系统,通常被称为"proc文件系统"或"procfs"。这个文件系统以文件系统的方式为内核与进程之间的通信提供了一个接口。/proc目录中的文件大多数都提供了关于系统状态的信息&#xff0…

计算Dice损失的函数

计算Dice损失的函数 def Dice_loss(inputs, target, beta1, smooth 1e-5):n,c, h, w inputs.size() #nt,ht, wt, ct target.size() #nt,if h ! ht and w ! wt:inputs F.interpolate(inputs, size(ht, wt), mode"bilinear", align_cornersTrue)temp_inputs t…

MySQL之如何分析慢查询

1、一个SQL语句执行很慢,如何分析? 可使用“explain”或者“desc”命令获取MySQL如何执行select语句的信息。 语法:直接在select语句前加关键字 explain或desc explain select job_desc from xxl_job_info where id 1; 2、执行计划中五个重…

【刷题】初步认识深搜(DFS)

送给大家一句话: 拥有希望的人,和漫天的星星一样,是永远不会孤独的。 -- 《星游记》 初步认识深搜(DFS) dfs算法二叉树中的深搜Leetcode 129. 求根节点到叶节点数字之和题目描述算法思路 Leetcode 814. 二叉树剪枝题…

FreeRTOS的裁剪与移植

文章目录 1 FreeRTOS裁剪与移植1.1 FreeRTOS基础1.1.1 RTOS与GPOS1.1.2 堆与栈1.1.3 FreeRTOS核心文件1.1.4 FreeRTOS语法 1.2 FreeRTOS移植和裁剪 1 FreeRTOS裁剪与移植 1.1 FreeRTOS基础 1.1.1 RTOS与GPOS ​ 实时操作系统(RTOS):是指当…

C语言中常用的运算符、表达式和语句

C语言是一种通用的、高级的编程语言,其历史可以追溯到20世纪60年代末至70年代初。C语言最初是由丹尼斯里奇(Dennis Ritchie)在贝尔实验室为开发UNIX操作系统而设计的。它继承了许多B语言的特性,而B语言则是由迷糊老师(…

基于YOLOv9+pyside的安检仪x光危险物物品检测(有ui)

安全检查在公共场所确保人身安全的关键环节,不可或缺。X光安检机作为必要工具,在此过程中发挥着重要作用。然而,其依赖人工监控和判断成像的特性限制了其应用效能。本文以此为出发点,探索了基于Torch框架的YOLO算法在安检X光图像中…

spring和springboot的关系是什么?

大家好,我是网创有方的站长,今天给大家分享下spring和springboot的关系是什么? Spring和Spring Boot之间的关系可以归纳为以下几个方面: 技术基础和核心特性: Spring:是一个广泛应用的开源Java框架&#…

深入理解一致性Hash和虚拟节点

在分布式系统中架构中我们经常提到一致性哈希算法,那么什么是一致性哈希算法,为什么需要一致性哈希算法呢? 1、为什么需要一致性哈希算法 假设现在有三台缓存服务器(缓存服务器A、缓存服务器B、缓存服务器C)&#xff…

每日一题——Python实现PAT乙级1059 C语言竞赛(举一反三+思想解读+逐步优化)四千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 时间复杂度分析 空间复杂度分析 代码优化建议 总结 我要更强 优化方法…

fastadmin selectpage下拉框默认选中

修改 /public/assets/libs/fastadmin-selectpage/selectpage.js

C++【引用】

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:LiUEEEEE                        …

入门Java爬虫:认识其基本概念和应用方法

Java爬虫初探:了解它的基本概念与用途,需要具体代码示例 随着互联网的快速发展,获取并处理大量的数据成为企业和个人不可或缺的一项任务。而爬虫(Web Scraping)作为一种自动化的数据获取方法,不仅能够快速…