学习文件IO,让你从操作系统内核的角度去理解输入和输出(Java实践篇)

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

引言

在数字化时代,数据的存储、访问与处理已成为推动科技进步与社会发展的核心动力。

想象一下,从个人电脑的文档管理到企业级的数据中心,从智能手机上的照片备份到云端服务的海量数据存储,无一不依赖于一个关键而基础的技术—— 文件输入输出(File IO)

文件IO,作为连接数据世界与现实世界的桥梁,其重要性不言而喻。它不仅关乎数据的安全与效率,更是各类应用程序、操作系统乃至整个信息技术架构的基石。

让我们一同踏入这场探索之旅,揭开文件IO技术的神秘面纱,共同见证数据如何在指尖流转,成为推动世界前行的强大力量。

本篇文章中我们讲学习到以下内容

目录

  1. 文件系统操作

  2. 文件内容操作

  3. 文件综合运用操作

一. 文件系统操作

对于一个文件来说,我们可以得到一个文件的各种属性: 文件名,文件目录,文件路径。这里的就涉及到文件系统操作。

1. File类

Java标准库 中就封装了一个 FIle类 来获取文件的各种信息和属性

来自 java.io.File 这个包。

在这里插入图片描述

2. 常用方法

而作为一个后端开发的程序猿我们只需要了解 Java标准库 中的 File 类 中常用的几个方法即可:

  • 得到该 对象的文件名和上一个路径的文件

在这里插入图片描述

  • 得到该 对象的路径

在这里插入图片描述

  • 判断该对象是否是 绝对路径 或者 是否是一个目录

在这里插入图片描述

  • 判断该对象是否是 一个文件

在这里插入图片描述

  • 得到该目录下的 所有文件和目录

在这里插入图片描述

3. 代码演示

package FileDemo;import java.io.File;
import java.io.IOException;public class MyFileTest {public static void main(String[] args) throws IOException {File file = new File("./demo.txt");//        得到文件的绝对路径System.out.println(file.getAbsoluteFile());//        判断是否是目录if (file.isDirectory()) {System.out.println("是目录!");} else {System.out.println("不是目录!");}//        判断是否是路径if (file.isAbsolute()) {System.out.println("是路径!");} else {System.out.println("不是路径!");}//        得到上一级的文件File[] files = file.getParentFile().listFiles();//        开始遍历for (File f : files) {
//           判断是否是文件if (f.isFile()) {System.out.println(f.getName());}}}
}

在这里插入图片描述

在上面的演示中

主要分为两部进行

  1. 文件对象的实例
File file = new File("./demo.txt");
  1. 进行各种文件系统操作
//        得到文件的绝对路径System.out.println(file.getAbsoluteFile());

等… 这些操作将在下面内容中结合 文件内容操作 一起配合使用~

鱼式疯言

  1. 使用 File 类来实例化对象 时, 也是会成功的,

但需要判断的是是否是 符合要求目录路径

  1. 需要抛出 异常 IOException 这个异常, 并且导入 Java.io.IOException 这个包.

二. 文件内容操作

在文件内容操作的之前,小伙伴们必须先了解一下流对象,以及流对象的表示形式。

1. 流对象

什么是流 ? ? ?

流可以说水流,气流等…

但在文件IO这里,流的作用主要是处理各种各样的文件形式而形成的一种 统一的概念

而流分为两种:

1) 字节流

2) 字符流

<1>. 字节流

字节流的含义就好比现在你有一百个字节数据

如果一个字节一个字节取,就需要取一百次;
如果五个字节五个字节取,就需要取二十次;
如果十个字节十个字节取,就需要取十次;
如果二十个字节二十个字节取,就需要取五次;
如果一百个字节一百个字节取,只需取一次。

这就是字节流,先把数据 以字节为基本单位 进行划分,根据 需求 得到每次 需要取出字节的个数 来进行 文件IO内容操作

代表的类:

  • 以字节为单位的读操作的类

InputStream

  • 以字节为单位的写操作的类

OutputStream

<2>. 字符流

字符流的含义就好比现在你有一百个字符数据

如果一个字符一个字节取,就需要取一百次;
如果五个字符五个字节取,就需要取二十次;
如果十个字符十个字节取,就需要取十次;
如果二十个字符二十个字节取,就需要取五次;
如果一百个字符一百个字节取,只需取一次。

字符流是以字符为 基本单位对文件内容进行划分并操作

代表的类:

  • 以字符为单位的读操作的类:
    Reader

  • 以字符为单位的写操作的类:
    Writer

2. 字符流代码演示

<1>. 读操作


package MyIODemo;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;public class ReaderDemo {public static void main(String[] args) throws IOException {// 实例化字符流读操作的FileReader类// 打开文件Reader reader = new FileReader("demo1.txt");//        利用文件流对文件进行读操作
//        通过循环遍历每次读的字符while(true) {// 将每次读到的字符 用 n 来接收int n = reader.read();// 一旦返回 -1 说明读取到文件的最后一个位置,读取完毕if(n== -1) {break;}// 转化为字符并打印输出char buffer = (char) n;System.out.print(buffer);}//        关闭文件流reader.close();}
}

在这里插入图片描述

读操作 用到的 Reader类 来自 java.io.Reader 这个包, 而且需要抛出 IOException 这个类.

鱼式疯言

总结一 :

文件内容操作的流程三部曲:

  1. 打开文件
  1. 读写文件内容
  1. 关闭文件

总结二 :

FileNotFoundException 是进行打开文件是 所需要抛出的异常 , 但属于 IOException , 所以这里我们只需要抛出 IOException 即可。

<2>. 写操作

package MyIODemo;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Scanner;public class WriterDemo {public static void main(String[] args) throws IOException {//       打开文件Writer writer = new FileWriter("demo1.txt",true);Scanner in = new Scanner(System.in);String  buffer = in.nextLine();//        写文件writer.write(buffer);//        关闭文件writer.close();}
}

在这里插入图片描述

结论一 :

对于 写操作 , 还是按照三个流程:

  1. 打开文件
  1. 写文件
  1. 关闭文件

结论二:

//       打开文件Writer writer = new FileWriter("demo1.txt",true);

当我们打开文件时:

FileWriter 方法还设定了 一个参数 , 这个参数的如果置为 true 就代表不会清空全有数据而是在原有数据的后面进行拼接写入。

如果在参数列表 ==不添加 true 或者置为 false ==, 就会 清空内容,从一个 空文档 开始写入。

鱼式疯言

关于 文件关闭 这件事,小编有话说

在操作系统内核中,每打开一个文件,就会在操作系统中的一个特点的区域: “文件描述符表” 中多一个

这个 文件描述符表 可以看成是 一个数组 , 一旦打开文件过多没有及时关闭 ,就会在 文件描述符表中 不断堆积 , 就会导致出现 文件泄露问题

虽然进程结束,程序会 自动清空文件描述符表中的每一项 , 但是如果程序一直 不结束,就会导致 不可预估的问题 发现。

所以小编在这里建议: 加上 close() 方法来 释放文件资源

3. 字节流代码演示

<1>. 读操作

package MyIODemo;import java.io.*;
import java.util.Scanner;/*** 基本版本的读入文件*/
public class StreamTest {public static void main(String[] args) {try(InputStream inputStream = new FileInputStream("./demo.txt")){while(true) {byte[] buffer = new byte[1024];int flg = inputStream.read(buffer);if(flg == -1) {break;}for (int i = 0; i < flg; i++) {System.out.print((char) buffer[i]);}}} catch (IOException e) {e.printStackTrace();}}
}

在这里插入图片描述
这里字节流的读操作

  1. 打开文件

小编利用了 try() catch {} 进行操作。

利用 try (打开文件) , 在这个括号打开文件 在{} 内生效,出来{} 就会自动关闭 文件流 。 这样就可以省去手动 close()关闭文件

byte[] buffer = new byte[1024];int flg = inputStream.read(buffer);
  1. 在读文件时,我们就需要注意声明一个 byte[] 类型 的数组, 用来 存储文件中的数据, 只需要放入 read 的参数中 即可填充 , 而 flg 的这个返回值就是作为 数组实际填充 的大小, 如果一旦 flg = -1 时, 就说明数据已经返回结束了。

其他操作和上面字符流大体一致,小编在这就不赘述啦 💖 💖

鱼式疯言

注意事项

只有这种特定的 打开文件类似的操作 才能放入 try () 的括号内, 且如果要放 多行 的话,就需要用 ; 号来隔开。 作用域就是在 { }

<2>. 写操作

package MyIODemo;import java.io.*;
import java.util.Scanner;/*** 基本版本的写入文件*/
class StreamTest2 {public static void main(String[] args) {try(OutputStream outputStream = new FileOutputStream("./demo.txt",true)) {byte[] buffer = {97,98,99};outputStream.write(buffer);}catch (IOException e){e.printStackTrace();}}
}

在这里插入图片描述

字节流的写操作也大同小异,小编在这里就不赘述, 小伙伴好好理解即可。

三. 文件综合运用操作

学会了文件系统和文件内容的各个基础操作,下面小编就举出两个实际的案例给小伙伴演示下两者结合的秒出哦 , 可千万别眨眼哦 💖 💖 💖 💖

1. 找到指定文件确认是否删除

<1>. 逻辑分析

  1. 首先: 先确认该文件的路径
  1. 其次: 在 路径合法 的情况下, 把每个文件目录取出进行递归查找
  1. 最后:在是合法文件的提前下, 判断是否含有 该文件名 ,一旦含有就选择 是否需要删除

<2>. 代码展示

/*** 查找指定文件并且删除**/package MyIODemo;import java.io.*;
import java.util.Scanner;class StreamTest4 {public static void main(String[] args) {// 确定路径System.out.print("请输入指定路径: ");Scanner in = new Scanner(System.in);String path = in.next();// 转化成路径File  pathRoot = new File(path);//        判断是否是合法路径if(!pathRoot.isDirectory()) {System.out.println("不是合法路径!");return;}// 输入指定文件System.out.print("请输入指定的文件的关键字: ");String key = in.next();// 进行递归scan(pathRoot, key);}private static void scan(File pathRoot, String key) {// 判断当前路径是否合法if(!pathRoot.isDirectory()) {return;}// 合法的情况下取出当前所以的路径File[] files = pathRoot.getAbsoluteFile().listFiles();// 多加一层判断if (files== null || files.length == 0) {return;}// 深度优先遍历 所以的文件路径for(File file : files) {if(file.isFile()) {
//                是文件的话就开始判断是不是指定文件
//                然后进行删除delete(file, key);} else {// 继续往下递归scan(file,key);}}}private static void  delete(File file, String key) {if(file.getName().contains(key)) {System.out.println("请确定是否删除该文件:" + file.getAbsoluteFile() + " Y/y -> 是, N/n -> 否 :  ");Scanner in = new Scanner(System.in);String  str = in.next();if(str.equals("y") || str.equals("Y")) {file.delete();System.out.println("删除成功!");} else {System.out.println("删除失败,正在退出...");}}}}

在这里插入图片描述

在这里插入图片描述

2. 进行文件的复制

<1>. 逻辑分析

  1. 首先输入第一个字符串为 源文件, 判断是否是 合法文件
  1. 其次输入第二个字符串为 目标文件, 判断是否是 合法文件
  1. 最后在 try catch 中实例化 字节输出和输入流 ,先对源文件进行 读操作 , 然后再对目标文件进行 写操作。当源文件 读取结束 ,目标文件也就完成了 拷贝

<2>. 代码展示

/**** 将一个文件拷贝到另外一个文件**/import java.io.*;
import java.util.Scanner;class StreamTest5 {public static void main(String[] args) {System.out.print("请输入源文件路径: ");Scanner in = new Scanner(System.in);String path = in.next();File curPath = new File(path);// 判断是否合法路径// 是否是正确的文件if(!curPath.isFile()) {System.out.println("源文件非法!");return;}// 判断是否合法System.out.print("请输入目标文件的路径: ");path = in.next();File descPath = new File(path);if (!curPath.getParentFile().isDirectory()) {System.out.println("目标文件路径非法");return;}// 开始进行读入 和写出try (InputStream inputStream = new FileInputStream(curPath) ;OutputStream outputStream = new FileOutputStream(descPath)) {byte[] buffer = new byte[1024];// 从源文件读入, 写出到目标文件while(true) {//               读入int n = inputStream.read(buffer);if(n==-1) {break;}// 写出outputStream.write(buffer,0,n);}System.out.println("拷贝成功! ");} catch (IOException e) {e.printStackTrace();}}
}

在这里插入图片描述

总结

  • . 文件系统操作: 利用 File 这个类对文件的 路径,目录,判断 进行各种操作。

  • . 文件内容操作: 熟悉了 文件流 的 字节流和 字符流 的 概念理解 , 以及对于 FileReader , IntputStream 的读操作, 和 FileWriterOutputStream写操作

  • . 文件综合运用操作: 综合 结合了两种不同的 文件系统操作和文件内容操作 结合学习,实际运用了具体的实际运用中。

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经验之谈 —— 数据处理与分析的6大Python库

点击下方卡片&#xff0c;关注“小白玩转Python”公众号 Python是一种流行的高级编程语言。它拥有丰富的生态系统和庞大的社区。这个生态系统中有许多优秀的Python库。这些库提供了有用的工具&#xff0c;使开发变得更加容易。本文将介绍6个出色的Python库。这些库在不同领域都…

数据结构初阶(2)——链表OJ

目录 1.面试题 02.02. 返回倒数第 k 个节点 2.OR36 链表的回文结构 3.160. 相交链表 1.面试题 02.02. 返回倒数第 k 个节点 思路&#xff1a;快慢指针&#xff0c;快指针先走k格&#xff0c;慢指针同步 /*** Definition for singly-linked list.* struct ListNode {* i…

android13 隐藏状态栏里面的飞行模式 隐藏蓝牙 隐藏网络

总纲 android13 rom 开发总纲说明 目录 1.前言 2.问题分析 3.代码分析 4.代码修改 5.编译运行 6.彩蛋 1.前言 android13 隐藏状态栏里面的飞行模式,或者其他功能,如网络,蓝牙等等功能,隐藏下图中的一些图标。 2.问题分析 这里如果直接找这个布局的话,需要跟的逻…

[数据集][目标检测]电力场景输电线杆塔塔架金属锈蚀腐蚀生锈检测数据集VOC+YOLO格式1344张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1344 标注数量(xml文件个数)&#xff1a;1344 标注数量(txt文件个数)&#xff1a;1344 标注…

(南京观海微电子)——直流电源使用介绍

什么是稳压电源&#xff1f;直流稳压电源使用方法教程 在电子技术领域中&#xff0c;稳压电源扮演着举足轻重的角色。那么&#xff0c;究竟什么是稳压电源呢&#xff1f;稳压电源是一种能够提供稳定输出电压的电子装置&#xff0c;其核心功能是在输入电压波动或负载变化的情况…

i.MX6裸机开发(9):CCM时钟控制模块

本章参考资料&#xff1a;《IMX6ULRM》&#xff08;参考手册&#xff09;。 学习本章时&#xff0c;配合《IMX6ULRM》第18章Clock Controller Module (CCM)&#xff0c;效果会更佳&#xff0c;特别是涉及到寄存器说明的部分。 本章我们主要讲解时钟部分&#xff0c;芯片内部的…

摄影曝光:曝光模式认知

写在前面 学习整理《摄影曝光&#xff1a;拍出好照片的49个关键技法》读书笔记博文内容涉及曝光模式简单认知适合小白认知理解不足小伙伴帮忙指正 &#x1f603;,生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c;所以唯一的解决办法就是行动起来&#xff0c;认真…

【Docker】Docker Consul

docker consul Docker Consul 是一个用于服务发现和配置的开源工具&#xff0c;它是 HashiCorp 公司推出的一个项目。Consul 提供了一个中心化的服务注册和发现系统&#xff0c;可以帮助开发人员轻松地在 Docker 容器和集群之间进行服务发现和配置管理。 Consul 使用基于 HTT…

SQL注入漏洞的基础知识

目录 SQL注入漏洞的定义和原理 SQL注入的类型和攻击方法 SQL注入的防御措施 示例代码 深入研究 SQL注入漏洞的常见攻击场景有哪些&#xff1f; 如何有效防范SQL注入攻击&#xff1f; SQL注入与跨站脚本攻击&#xff08;XSS&#xff09;之间有什么区别&#xff1f; 主要…

CORS错误

说明&#xff1a;记录一次CORS&#xff08;跨域&#xff09;错误&#xff0c;及解决方法。 场景 在vscode里面运行前端项目&#xff0c;idea中运行后端项目&#xff0c;登录时&#xff0c;访问接口&#xff0c;报CORS错误&#xff0c;如下&#xff1a; 解决 在后端项目的网关…

electron仿微信,高度还原,入门项目

效果展示 Electron仿写微信-效果展示 目前完成了一些基础的功能&#xff0c;还在持续开发中&#xff0c;后期会整理开源。 有些样式没有追求百分百还原&#xff0c;只是通过该项目&#xff0c;让大家了解一下Electron创建桌面应用&#xff0c;各种窗口的创建及销毁、事件传递机…

GATK ReadsPathDataSource类介绍

GATK&#xff08;Genome Analysis Toolkit&#xff09;是一个广泛使用的基因组分析工具包&#xff0c;它的核心库之一是htsjdk&#xff0c;用于处理高通量测序数据。在GATK中&#xff0c;ReadsPathDataSource类是负责管理和提供读取高通量测序数据文件&#xff08;如BAM、SAM、…

【UE】尝试一种老派的平面假反射做法,与进一步改进效果的思路

在实践中&#xff0c;常常需要为类似荧幕&#xff0c;LED广告牌等平面制作反射。 但会遇到各种问题&#xff0c;例如在使用屏幕空间反射时&#xff0c;平面必须在画面内 平面反射捕获与光线追踪又代价高昂 因此&#xff0c;在一些情况下依然会使用一种历史悠久的反射手法 这种…

Windows SDK(九)登录框和计算器练习

这节课我们分别开始讲解登录框和计算机的实现 登录框实现 我们以上节课所学&#xff0c;自行创建一个对话框&#xff0c;ID为IDD_DIALOG1并将他编辑为一个登录框的样式。其中我们将账户的编辑框ID设置为IDC_ENIT_USERNAME&#xff0c;密码的编辑框ID设置为IDC_ENIT_PASSWORD。…

Pytorch构建网络模型结构都有哪些方式

目录 前言 1.使用nn.Module基类 2.使用nn.Sequential容器 3. 使用nn.ModuleList 4. 使用nn.ModuleDict 5. 混合使用nn.Module和原生Python代码 6.表格总结 前言 nn.Module&#xff1a;最通用、最灵活的方式&#xff0c;适用于几乎所有场景。nn.Sequential&#xff1a;适…

【HTML】为网页添加表单(控件)

1、表单 表单控件&#xff1a;包含了具体的表单功能项&#xff0c;如单行文本输入框、密码输入框、复选框、提交按钮、重置按钮等。 提示信息&#xff1a;一个表单中通常需要包含一些说明性的文字&#xff0c;提示用户进行填写和操作。 表单域&#xff1a;相当于一个容器&…

改造小蚁摄像头支持免费无限容量云储存(Samba挂载篇)

为什么要改造&#xff1f; 插卡摄像头最大的一个问题就是频繁的读写会导致内存卡寿命急速下降&#xff0c;哪怕是市面上支持NAS转存的摄像头也是先录制到SD卡里&#xff0c;然后把SD卡上的视频再转存到NAS。同样对内存卡和NAS硬盘寿命都是损耗巨大。而这类监控视频绝大多数情况…

深入理解Elasticsearch:让搜索性能飞起来!

Elasticsearch 概述 Elasticsearch是一个基于lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。 ELK 技术栈是Elasticsearch、Logstash、Kibana三大开元框架首字母大写简称。 而Elasticsearch 是一个开源的高扩展的分布式全文搜索引擎&#xff0c; 是整个 ELK技术…

ue5远程渲染和本地渲染的区别,及云渲染的联系

UE5这款引擎以其令人惊叹的渲染能力&#xff0c;为游戏开发者们打开了一扇通往视觉盛宴的大门。但是在UE5的世界里&#xff0c;渲染技术其实还有着本地渲染和远程渲染之分&#xff0c;而且它们与时下大热的云渲染技术也有着千丝万缕的联系。本文主要说明UE5中的远程渲染和本地渲…

Flask+LayUI开发手记(四):弹出层实现增删改查功能

在上一节用dataTable实现数据列表时&#xff0c;已经加了表头工具栏和表内工具栏&#xff0c;栏内的按钮功能都是用来完成数据的增删改查了&#xff0c;这又分成两类功能&#xff0c;一类是删除或设置&#xff0c;这类功能简单&#xff0c;只需要选定记录&#xff0c;然后提交到…