当前位置: 首页 > news >正文

JavaEE:文件内容操作(一)

文章目录

  • 文件内容的读写---数据流
    • 字节流和字符流
    • 打开和关闭文件
      • 文件资源泄漏
        • 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异常,所以要再加上一层trytry {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,留到下一篇文章讲吧~

本文到这里就结束啦~

相关文章:

JavaEE:文件内容操作(一)

文章目录 文件内容的读写---数据流字节流和字符流打开和关闭文件文件资源泄漏try with resources 文件内容的读写—数据流 文件内容的操作,读文件和写文件,都是操作系统本身提供了API,在Java中也进行了封装. Java中封装了操作文件的这些类,我们给它们起了个名字,叫做"文…...

无人机视角下落水救援检测数据集

无人机视角下落水救援检测数据集,利用无人机快速搜索落水者对增加受害者的生存机会至关重要,该数据集共收集12万帧视频图像,涵盖无人机高度从10m-60m高度,检测包括落水者(11万标注量)、流木(900…...

openssl+keepalived安装部署

文章目录 OpenSSL安装下载地址编译安装修改系统配置版本 Keepalived安装下载地址安装遇到问题安装完成配置文件 keepalived运行检查运行状态查看系统日志修改服务service重新加载systemd检查配置文件语法错误 OpenSSL安装 下载地址 ​ 考虑到后面设备可能没法连接到外网&…...

float存储原理

float存储原理基于IEEE 754标准,主要包括符号位、指数位和有效数字位三部分。以下是对其存储原理的具体介绍: 符号位:符号位是浮点数中用于表示正负的位。在单精度浮点数(32位)中,最左边的第1位是符号位&a…...

DAY 9 - 10 : 树

树的概念 定义 树(Tree)是n(n≥0)个节点的有限集合T,它满足两个条件 : 1.有且仅有一个特定的称为根(Root)的节点。 2.其余的节点可以分为m(m≥0)个互不相交的…...

【python计算机视觉编程——9.图像分割】

python计算机视觉编程——9.图像分割 9.图像分割9.1 图割安装Graphviz下一步:正文9.1.1 从图像创建图9.1.2 用户交互式分割 9.2 利用聚类进行分割9.3 变分法 9.图像分割 9.1 图割 可以选择不装Graphviz,因为原本觉得是要用,后面发现好像用不…...

北斗赋能万物互联:新质生产力的强劲驱动力

在数字化转型的大潮中,中国自主研制的北斗卫星导航系统,作为国家重大空间基础设施,正以前所未有的力量推动着万物互联时代的到来,成为新质生产力发展的重要基石。本文将深入剖析北斗系统如何以其独特的技术优势和广泛应用场景&…...

时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测

时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测 目录 时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 | Matlab实现GA-CNN遗传算法优化卷积神经网络时间序列预测&#xff…...

如何保证消息不重复消费

在使用消息队列(Message Queue, MQ)时,确保消息不被重复消费是非常重要的,因为重复消费可能导致数据不一致或者业务逻辑出错。要保证消息不被重复消费,可以采取以下几种策略: 1. 消息确认机制 大多数消息…...

HTTP请求工具类

HTTP请求工具类 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL;public class HttpUtils {/*** 发送GET请求并获取响应结果* * param url 请求的URL* return 响应结果…...

谷歌的 DataGemma 人工智能是一个统计精灵

谷歌正在扩大其人工智能模型家族,同时解决该领域的一些最大问题。 今天,该公司首次发布了 DataGemma,这是一对开源的、经过指令调整的模型,在缓解幻觉挑战方面迈出了一步,幻觉是指大型语言模型(LLM&#xf…...

【Python爬虫系列】_021.异步请求aiohttp

课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈...

源码运行springboot2.2.9.RELEASE

1 环境要求 java 8 maven 3.5.2 2 下载springboot源码 下载地址 https://github.com/spring-projects/spring-boot/releases/tag/v2.2.9.RELEASE 3 修改配置 修改spring-boot-2.2.9.RELEASE/pom.xml 修改spring-boot-2.2.9.RELEASE/spring-boot-project/spring-boot-tools…...

王者荣耀改重复名(java源码)

王者荣耀改重复名 项目简介 “王者荣耀改重复名”是一个基于 Spring Boot 的应用程序,用于生成王者荣耀游戏中的唯一名称。通过简单的接口和前端页面,用户可以输入旧名称并获得一个新的、不重复的名称。 功能特点 生成新名称:提供一个接口…...

Python 全栈系列271 微服务踩坑记

说明 这个坑花了10个小时才爬出来 碰到一个现象:将微服务改造为并发后,请求最初很快,然后就出现大量的失败,然后过一会又能用。 过去从来没有碰到这个问题,要么是一些比较明显的资源,或者逻辑bug&#xff0…...

环境搭建2(游戏逆向)

#include<iostream> #include<windows.h> #include<tchar.h> #include<stdio.h> #pragma warning(disable:4996) //exe应用程序 VOID PrintUI(CONST CHAR* ExeName, CONST CHAR* UIName, CONST CHAR* color, SHORT X坐标, SHORT y坐标, WORD UIwide, W…...

快手自研Spark向量化引擎正式发布,性能提升200%

Blaze 是快手自研的基于Rust语言和DataFusion框架开发的Spark向量化执行引擎&#xff0c;旨在通过本机矢量化执行技术来加速Spark SQL的查询处理。Blaze在快手内部上线的数仓生产作业也观测到了平均30%的算力提升&#xff0c;实现了较大的降本增效。本文将深入剖析blaze的技术原…...

用网卡的ap模式抓嵌入式设备的网络包

嵌入式设备不像pc上&#xff0c;有一些专门的工具比如wareshark来抓包&#xff0c;嵌入式设备中&#xff0c;有的可能集成了tcpdump&#xff0c;可以用来进行简单的抓包&#xff0c;但是不方便分析&#xff0c;况且有的嵌入式设备不一定就集成了tcpdump工具。 关于tcpdump工具…...

centos 7 升级Docker 与Docker-Compose 到最新版本

一 升级docker 可参考docker官方升级 1, 查看docker 信息 docker info 2,查看docker 版本 docker --version 3 升级前 可停止docker : sudo systemctl stop docker 4 查看已安装的docker 并卸载 [rootlocalhost docker]# yum list installed | grep docker docker.x86…...

Docker_启动redis,容易一启动就停掉

现象以及排查过程 最近在使用docker来搭建redis服务&#xff0c;但是在启动redis哨兵容器时&#xff0c;总是发现这个容器启动后立马就停止了。首先想到的是不是服务器资源不够用了导致的这个现象&#xff0c;排查后发现不是资源问题。再者猜测是不是启动报错了&#xff0c;查看…...

微服务中间件之Nacos

Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它提供了服务注册与发现、配置管理以及服务健康监测等核心功能&#xff0c;旨在帮助开发人员更轻松地构建和管理微服…...

C++: 类和对象(上)

&#x1f4d4;个人主页&#x1f4da;&#xff1a;秋邱-CSDN博客☀️专属专栏✨&#xff1a;C&#x1f3c5;往期回顾&#x1f3c6;&#xff1a;从C语言过渡到C&#x1f31f;其他专栏&#x1f31f;&#xff1a;C语言_秋邱 ​ 面向过程和面向对象 C 语言被认为是面向过程的编程…...

Unity程序基础框架

概述 单例模式基类 没有继承 MonoBehaviour 继承了 MonoBehaviour 的两种单例模式的写法 缓存池模块 &#xff08;确实挺有用&#xff09; using System.Collections; using System.Collections.Generic; using UnityEngine;/// <summary> /// 缓存池模块 /// 知识点 //…...

TiDB 数据库核心原理与架构_Lesson 01 TiDB 数据库架构概述课程整理

作者&#xff1a; 尚雷5580 原文来源&#xff1a; https://tidb.net/blog/beeb9eaf 注&#xff1a;本文基于 TiDB 官网 董菲老师 《TiDB 数据库核心原理与架构&#xff08;101) 》系列教程之 《Lesson 01 TiDB 数据库架构概述》内容进行整理和补充。 课程链接&#xff1a;…...

计算机毕业设计Python深度学习垃圾邮件分类检测系统 朴素贝叶斯算法 机器学习 人工智能 数据可视化 大数据毕业设计 Python爬虫 知识图谱 文本分类

基于朴素贝叶斯的邮件分类系统设计 摘要&#xff1a;为了解决垃圾邮件导致邮件通信质量被污染、占用邮箱存储空间、伪装正常邮件进行钓鱼或诈骗以及邮件分类问题。应用Python、Sklearn、Echarts技术和Flask、Lay-UI框架&#xff0c;使用MySQL作为系统数据库&#xff0c;设计并实…...

多核DSP(6000系列)设计与调试技巧培训

​课程介绍&#xff1a; 为帮助从事DSP开发工程师尽快将DSP技术转化为产品&#xff0c;在较短时间内掌握DSP设计技术和问题的解决方法&#xff0c;缩短产品开发周期、增强产品竞争力、节省研发经费。我们特组织了工程实践和教学经验丰富的专家连续举办了多期DSP C6000的培训&a…...

JMeter脚本开发

环境部署 Ubuntu系统 切换到root用户 sudo su 安装上传下载的命令 apt install lrzsz 切换文件目录 cd / 创建文件目录 mkdir java 切换到Java文件夹下 cd java 输入rz回车 选择jdk Linux文件上传 解压安装包 tar -zxvf jdktab键 新建数据库 运行sql文件 选择sql文件即…...

LabVIEW编程快速提升的关键技术

在LabVIEW程序员的成长道路上&#xff0c;以下几个概念和技术的掌握可以显著提升自我能力&#xff1a; 模块化编程&#xff1a;学会将程序分解成小而独立的模块&#xff08;如子VI&#xff09;&#xff0c;提高程序的可读性、可维护性和可扩展性。这种方式不仅能帮助快速定位问…...

BSN六周年:迈向下一代互联网

当前&#xff0c;分布式技术作为现代计算机科学和信息技术的重要组成部分&#xff0c;在云计算、区块链等技术的推动下&#xff0c;正以多样化的形式蓬勃发展。 ​而区块链作为一种特殊的分布式系统&#xff0c;近年来也在各个领域得到了广泛关注。通过在区块链上运行智能合约…...

Android 使用scheme唤起app本地打开

记录一下近期任务。。。 以下操作全部基于手机本地已经安装对应app方可执行。 没安装建议web前端校验一下跳动app下载页吧。 AndroidManifest配置如下&#xff1a; <activity android:name".RouterActivity"><intent-filter><dataandroid:host&quo…...