JavaEE:文件内容操作(一)

news2024/9/22 23:33:17

文章目录

  • 文件内容的读写---数据流
    • 字节流和字符流
    • 打开和关闭文件
      • 文件资源泄漏
        • try with resources


文件内容的读写—数据流

文件内容的操作,读文件和写文件,都是操作系统本身提供了API,在Java中也进行了封装.

Java中封装了操作文件的这些类,我们给它们起了个名字,叫做"文件流" / “IO流”.

IO流的特点:
我要从文件中读取100字节的数据,有以下几种读法.

  1. 直接一口气,把100字节都读完.
  2. 一次读50字节,分两次.
  3. 一次读10字节,分10次.
  4. 一次读1字节,分100次.

字节流和字符流

Java实现IO流的类有很多,可以分成两个大的类别.

  1. 字节流(二进制): 读写数据的基本单位,就是字节.
    InputStream
    OutputStream
  2. 字符流(文本): 读写数据的基本单位,就是字符.(字符流内部做的工作会更多一些,会自动的查询码表,把二进制数据,转换成对应的字符)
    Reader
    Writer

上述这四个类,都是"抽象类",实际上真正干活的,并非是上面这四个.
另外,Java中提供了很多很多类,来实现上述的这个四个抽象类.

在这里插入图片描述

打开和关闭文件

使用InputStream来去读取文件:
我们先手动在当前目录下创建一个文件,文件内容为hello.
在这里插入图片描述

创建一个FileInputStream对象,通过指定文件路径来获取输入流。

package javaEE.fileIO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class J {
    // FileNotFoundException这个异常,是IOException的子类(IOException的特殊情况)
    public static void main(String[] args) throws IOException {
        // 因为InputStream是一个抽象类,我们不能直接new,只能new一个实现这个类的子类.
        // FileInputStream的括号内既可以指定绝对路径,也可以指定File对象.
        InputStream inputStream = new FileInputStream("./test.txt");
        // 在上述操作中,还隐含了一个操作"打开文件".
        // 与打开相对的还有一个关闭操作
        inputStream.close();
    }
}

InputStream 只是一个抽象类,要使用还需要具体的实现类。关于 InputStream 的实现类有很多,基本可以认为不同的输入设备都可以对应一个 InputStream 类,我们现在只关心从文件中读取,所以使用FileInputStream.

上述代码,只写成这样,其实是有风险的.
如果中间出现一些return操作或者抛出异常的操作,这些都会导致close()执行不到.

较好的写法还在后面~

文件资源泄漏

如果我们不使用close关闭,会咋样呢?
打开文件实际上实在该进程的文件描述符中,创建了一个新的表项.

之前写过进程 与 PCB(进程控制)的关系,这里就不再解释了.
文件描述符:描述了1该进程,都要操作那些文件,文件描述符,可以认为是一个数组,数组的每个元素就是一个struct file对象(Linux内核),每个结构体就描述了对应操作的文件的信息,数组的下标,就称为"文件描述符".

每一次打开一个文件,就相当于在数组上占用了一个位置,而在系统内核中,文件描述符数组,是固定长度并且不可扩容的.
除非主动调用close,关闭文件,此时,才会释放出空间.如果代码里一直打开,不去关闭,就会使这里的资源越来越少.
如果把数组搞满了,后续再打开文件,就会打开失败.

这个问题称为"文件资源泄漏".
这种问题,也是属于对程序员非常不友好的问题.
当文件资源泄漏时,程序的逻辑,都是能正常执行的,看不出来有啥不对的地方.
这样的问题,不容易被发现.
泄漏不是一瞬间就泄漏完,而是一个持续的过程.整个问题直到所有的资源泄漏完毕,这一刻才会集中的爆发出来.

public static void main(String[] args) throws IOException {
        // 因为InputStream是一个抽象类,我们不能直接new,只能new一个实现这个类的子类.
        // FileInputStream的括号内既可以指定绝对路径,也可以指定File对象.
        InputStream inputStream = new FileInputStream("./test.txt");
        // 在上述操作中,还隐含了一个操作"打开文件".
        // 与打开相对的还有一个关闭操作
        inputStream.close();
    }

在上述代码中,虽然要求确实是使用完毕之后要关闭,但是局限于本代码,不写close也行.因为close之后,紧接着进程就结束了.
刚才说的close是释放文件描述符表里的元素,进程结束,意味着PCB就真个销毁,PCB上的文件描述符,就会整个释放.

InputStream inputStream = new FileInputStream("./test.txt");
inputStream.close();

上述代码,只写成这样,其实是有风险的.
如果中间出现一些return操作或者抛出异常的操作,这些都会导致close()执行不到.

为了确保close能被执行到,所以要把它放在finally里面.

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class J {
    public static void main(String[] args) throws IOException {
        // 由于inputStream在try里面,而finally不能共享到try中的作用域,所以我们要把InputStream定义在try外面.
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream("./test.txt");
        } finally {
            inputStream.close();
        }
    }
}

都写try和finally了,其实还可以写上catch.

    public static void main(String[] args){
        // 由于inputStream在try里面,而finally不能共享到try中的作用域,所以我们要把InputStream定义在try外面.
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream("./test.txt");
        } catch (IOException e) {
             e.printStackTrace();
        } finally {
            // 又因为close会抛出一个IO异常,所以要再加上一层try
            try {
                inputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

这么写代码确实更严谨了,但是看起来更复杂了.
其实,针对文件关闭这样的操作,我们还有一种更优雅的写法,即简单又可靠~

try with resources
public class J {
    public static void main(String[] args) throws FileNotFoundException {
        // 使用这种写法,我们不变写finally也不必写close了~
        try (InputStream inputStream = new FileInputStream("./test.txt")) {

        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

这其实是Java中引入的一种特殊的写法,叫做"try with resources".
也就是在try的括号里面,写上要管理的资源,这里的资源就会在try代码块结束的时候,自动去执行关闭操作.
这里()中创建的资源可以是多个.

需要注意的是:必须是实现了Closeable的接口,才能放到try的括号内~在这里插入图片描述

好像本文没咋写读取文件内容,光写close了.
emmm,留到下一篇文章讲吧~

本文到这里就结束啦~

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

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

相关文章

药品识别与分类系统源码分享

药品识别与分类检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer V…

Vue | Vue深入浅出——Vue中的render函数详解

1.render函数 在编写vue单文件的大多数情况下,我们都是使用template模板来创建HTML。然而在一些条件判断比较复杂的场景下,使用JavaScript去描绘HTML的生成逻辑会显得更加的简洁直观。 使用Vue官网的例子来简单说明: 如果自己在开发的时候…

vscode配置django环境并创建django项目

1、创建文件夹 创建文件夹 并在vscode打开 终端输入命令 “ python -m venv env ” 查看目录结构 2、创建项目 在终端输入 django-admin startproject 文件名(这里以myshop为例) 3、创建应用 在myshop打开终端 在终端输入 django-admin startapp 应用名 这里以app1为例…

6个免费icon图标素材网站

在这个数字化时代,优秀的图标设计对于提升用户体验至关重要。为了帮助设计师和开发者找到高质量的免费icon图标素材,我整理了以下6个实用的网站,让你轻松获取精美图标,助力你的设计工作。快来一起看看吧! 1、菜鸟图库 …

如何显示Dialog窗口

文章目录 1. 概念介绍2. 使用方法2.1 Overlay效果2.1 Dialog效果 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get显示snackBar"相关的内容,本章回中将介绍使用get显示Dialog.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

【卷起来】VUE3.0教程-07-异步请求处理(springboot后端)

&#x1f332; 服务端接口准备 pom文件&#xff0c;引入mybatis/mybatis-plus相关依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>&…

Split函数

Split:可以将一个完整的字符串按照指定的分隔符划分为若干个子字符串。 String[] split(String regex) :将字符串全部拆分. String[] split(String regex, int limit) :将字符串以指定的格式&#xff0c;拆分为limit 组 代码实例&#xff1a; 切割小数点&#xff0c;或\ ,需…

每日单词记背

2024年9月12日 1.discriminate&#xff1a;歧视&#xff0c;区别&#xff0c;分辨 discriminate against 歧视&#xff1b;排斥 discriminate between 区别 辨别 dis(区别)crim(罪犯)inate ->区别为罪犯->歧视 it is illegal to discriminate against women in any way.…

【Linux修行路】信号的产生

目录 ⛳️推荐 一、信号的产生 二、产生信号的系统调用 2.1 kill——给指定的进程发送指定的信号 2.2 模拟实现指令 kill 2.3 raise——给调用的进程发送指定的信号 2.4 abort——给调用者发送 6 号信号 三、验证哪些信号不可以被捕捉 四、为什么除0和解引用空指针会给…

数据库(DB、DBMS、SQL)

今天我来讲解一下数据库和可视化数据库管理系统的使用 数据库概述 数据库 存储数据的仓库&#xff0c;数据是有组织的存储 DataBase (DB) 数据库管理系统 操纵和管理数据库的大型软件 DataBaseMangement System (DBMS) SQL 操作关系型数据库的编程语言&#xff0c;定义…

探索最佳 Shell 工具:全面测评 Bash、Zsh、Fish、Tcsh 和 Ksh

感谢浪浪云支持发布 浪浪云活动链接 &#xff1a;https://langlangy.cn/?i8afa52 文章目录 1. 简介2. 测评工具3. 测评标准4. Bash 测评4.1 易用性4.2 功能特性4.3 性能4.4 可定制性4.5 社区和支持 5. Zsh 测评5.1 易用性5.2 功能特性5.3 性能5.4 可定制性5.5 社区和支持 6. F…

C++设计模式——Builder Pattern建造者模式

一&#xff0c;建造者模式的定义 建造者模式&#xff0c;又被称为生成器模式&#xff0c;是一种创建型设计模式&#xff0c;它将复杂产品的构建过程分解为一系列简单的步骤&#xff0c;每个步骤由独立的建造者对象负责。 建造者模式常用于创建复杂的对象&#xff0c;它避免了…

网络安全架构师

网络安全架构师负责构建全面的安全框架&#xff0c;以保护组织的数字资产免受侵害&#xff0c;确保组织在数字化转型的同时维持强大的安全防护。 摩根大通的网络安全运营副总裁兼安全架构总监Lester Nichols强调&#xff0c;成为网络安全架构师对现代企业至关重要&#xff0c;…

单向链表之创建,插入,输出(上)

文章目录 &#x1f34a;自我介绍&#x1f34a;创建&#x1f34a;插入&#x1f34a;输出 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以&#xff1a;点赞关注评论收藏&#xff08;一键四连&#xff09;哦~ &#x1f34a;自我介绍 Hello,大家好&#xff0c;我是小珑也要…

VMware Fusion虚拟机Mac版 安装Ubuntu操作系统教程

Mac分享吧 文章目录 下载镜像地址&#xff1a;[www.macfxb.cn](http://www.macfxb.cn)一、CentOS安装完成&#xff0c;软件打开效果二、Mac中安装Ubuntu虚拟机1️⃣&#xff1a;下载镜像2️⃣&#xff1a;创建虚拟机3️⃣&#xff1a;虚拟机设置4️⃣&#xff1a;虚拟机安装5️…

计算机三级 - 数据库技术 - 第十四章 数据仓库与数据挖掘 笔记

第十四章 数据仓库与数据挖掘 内容提要&#xff1a; 了解数据仓库相关技术了解数据仓库的设计、建造、运行及维护了解OLAP及多维数据模型了解数据挖掘技术 决策支持系统(DSS)&#xff1a;综合利用大量数据有机组合众多模型(数学模型和数据处理模型)&#xff0c;通过人机交互&a…

uniapp 端开发 echarts 树结构图

实现效果 &#xff1a; 1. 在uniapp 中写echarts 树结构图需要使用 <script module"echarts" lang"renderjs"> 否则会无法显示echarts 图形 rebderjs 代码 引入了 /static/echarts.min.js 是在 ECharts 在线构建 定制你的echarts <te…

001 RabbitMQ入门及安装

RabbitMQ入门及安装 文章目录 RabbitMQ入门及安装1.介绍1.AMQP和JMS2.目前主流的消息队列 2.安装1.Linux安装1.1 安装erlang1.2 RabbitMQ安装 2.Docker安装 3.核心组件 1.介绍 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦…

嵌入式音视频开发:探索多领域的融合与创新

摘要&#xff1a; 本文深入探讨了嵌入式音视频开发领域。从嵌入式系统的基础概念入手&#xff0c;阐述了其在音视频领域的独特地位。详细介绍了嵌入式音视频开发中涉及的硬件组件&#xff0c;如处理器、编解码器、存储设备等。分析了音视频编解码技术&#xff0c;包括常见的编解…

空间数据库概述

空间数据库简介 空间数据库是 地理信息系统 在计算机物理存储介质中存储的&#xff0c;与GIS应用相关的地理空间数据的总和。一般以一系列特定结构的文件形式组织后存储在介质上。 空间数据库的特点 可以存储、处理空间数据相比普通数据库提供更多、更复杂的数据类型以及更多…