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

【Java EE】文件IO

Author:MTingle
major:人工智能

---------------------------------------

Build your hopes like a tower!

目录

一、文件是什么?

二、针对文件系统操作的API

1.文件路径,文件名,文件是否存在

2. 创建文件

3.删除文件(*在线程结束时)

4. 创建File对象代表的⽬录

5. 文件改名及文件移动

三. 针对文件内容的操作(写文件 / 读文件)

1. 字节流(inputStream / outputStream)

1). 打开关闭文件 及 .read()

2). read一次读若干个字节

3). 读取汉字

4).写文件

2. 字符流(Reader / Writer)

3. 查找硬盘上文件的位置

4. 实现文件复制

3. 在目录中搜索,按照文件内容的方式搜索


一、文件是什么?

针对硬盘这种持久化存储的I/O设备,当我们想要进⾏数据保存时, 往往不是保存成⼀个整体,⽽是独⽴成⼀个个的单位进⾏保存,这个独⽴的单位就被抽象成⽂件的概 念,就类似办公桌上的⼀份份真实的⽂件⼀般。

二、针对文件系统操作的API

1.文件路径,文件名,文件是否存在

public class IODemo1 {public static void main(String[] args) throws IOException {File f=new File("./test.txt");System.out.println(f.exists());System.out.println(f.isFile());System.out.println(f.getName());System.out.println(f.getPath());System.out.println(f.getAbsolutePath());System.out.println(f.getCanonicalPath());}
}

2. 创建文件

public class IODemo2 {public static void main(String[] args) throws IOException {File f=new File("./test.txt");boolean ret=f.createNewFile();System.out.println("ret: "+ret);System.out.println(f.exists());}
}

3.删除文件(*在线程结束时)

public class IODemo3 {public static void main(String[] args) throws InterruptedException, IOException {
//        File file=new File("./test.txt");
//        boolean ret=file.delete();
//        System.out.println(ret);File file=new File("./test.txt");boolean ret=file.createNewFile();System.out.println("ret: "+ret);file.deleteOnExit();Thread.sleep(5000);}
}

4. 创建File对象代表的⽬录

public class IODemo4 {public static void main(String[] args) {File file=new File("./aaa/bbb/ccc");boolean ret=file.mkdirs();System.out.println(ret);}
}

5. 文件改名及文件移动

public class IODemo5 {public static void main(String[] args) {// 改名//        File src=new File("./test.txt");
//        File dest=new File("./test2.txt");
//        src.renameTo(dest);// 移动文件File src=new File("./test2.txt");File dest=new File("./aaa/test2.txt");src.renameTo(dest);}
}

三. 针对文件内容的操作(写文件 / 读文件)

在进行文件操作的时候,我们在结束操作的时候一定要调用 .close() 方法关闭文件,否则就会造成 文件资源泄露 / 内存泄漏 问题.

文件描述符表记录了当前进程都打开了哪些文件,每打开一个文件,都需要在文件描述符表中占据一个位置,如果不关闭的话,一直打开会造成文件描述符表被耗尽(文件描述符表有长度上限),当文件描述符表被耗尽,就会造成一系列的逻辑问题

1. 字节流(inputStream / outputStream)

以字节为单位,一次最少读写一个字节

1). 打开关闭文件 及 .read()

public class IODemo6 {public static void main(String[] args) throws IOException {// 打开文件
//            InputStream inputStream=null;
//        try {
//           inputStream=new FileInputStream("./test.txt");
//        }finally { // 防止文件结束时未执行到关闭位置,使用finally确保文件被关闭//关闭文件
//            inputStream.close();
//        }try (InputStream inputStream=new FileInputStream("./test.txt")){while (true) {int b=inputStream.read(); // 读到文件末尾,read会返回 -1 if (b==-1) {break;}System.out.printf("%x ",b);}}}
}

在此处我们更推荐使用第二种方法进行打开关闭文件,一旦出了 try 代码块,此时 try 自动帮我们调用inputStream的close方法.

此处的read方法,看起来是 int 类型,实际上是 byte ,实际的取值是 0- 255 ,此处有一个特殊情况,若读到文件末尾,则返回 -1 ,所以使用 int .

使用无参数版本,每次调用读取一个字节,返回值就表示读到的这个字节的值.

有参数版本中, offset 在此处表示偏移量

2). read一次读若干个字节

public class IODemo7 {public static void main(String[] args) throws IOException {// 一次读若干个字节try (InputStream inputStream=new FileInputStream("./test.txt")){while (true) {byte[] buffer=new byte[1024];int n=inputStream.read(buffer);if (n==-1) {break;}for (int i = 0; i < n; i++) {System.out.printf ("%x ",buffer[i]);}}}}}

read 的第二三个版本,返回的 int 表示实际读取的字节个数, buffer 是一个常见的术语,表示 "缓冲区",往往是一个内存空间,读文件就是把硬盘数据读取到内存中,上面这种写法,一次读取若干个字节,会比一次读取一个高效,类似的,一次写若干个字节,也比一次写一个字节更高效,操作硬盘本身就是一个比较低效的操作,期望低效的操作出现的次数越少越好,这样效率就会更高

3). 读取汉字

public class IODemo8 {public static void main(String[] args) throws IOException {// 一次读若干个字节(汉字)try (InputStream inputStream=new FileInputStream("./test.txt")){while (true) {byte[] buffer=new byte[1024];int n=inputStream.read(buffer);if (n==-1) {break;}String s=new String(buffer,0,n);System.out.println(s);}}}
}

此处的 String 是通过前 n 个字节构造,而不是整个数组,实际读取的文件内容可能不足1024

4).写文件

写文件与读文件类似,三个版本的含义也相似

public class IODemo9 {public static void main(String[] args) throws IOException {
//        try (OutputStream outputStream=new FileOutputStream("./test.txt")){
//            byte[] buffer=new byte[]{97,98,99,100,101,102};
//            outputStream.write(buffer);
//
//        }try (OutputStream outputStream=new FileOutputStream("./test.txt",true)){byte[] buffer=new byte[]{97,98,99,100,101};outputStream.write(buffer);}}
}

注释部分与未注释的部分的区别为少了一个 true ,当我们实施写操作打开文件的时候,注释版本中没有填 true ,系统默认为 false ,此时当我们打开文件时,会清空文件之前的所有内容,若我们不想把文件原来的内容清空,而是继续往下写文件,将内容写到文件的末尾,我们需要在末尾加上一个 true ,此时我们打开文件时就不会将原有的内容清空.

此处的参数 append 的含义为追加.

2. 字符流(Reader / Writer)

以字符为单位进行读写,一次最少读写一个字符,在utf8中,一个汉字需要三个字节来表示,所以读写汉字的时候,每次读写都需要以3个字节为单位进行,不能一次读写半个汉字. Reader 和 Writer 的使用和 inputStream outputStream 类似.只不过此时是按照 char 为单位操作了

public class IODemo10 {public static void main(String[] args) throws IOException {// 字符流读
//        try (Reader reader=new FileReader("./test.txt")) {
//            while (true) {
//                char[] buffer = new char[1024];
//                int n = reader.read(buffer);
//                if (n==-1) {
//                    break;
//                }
//                String s = new String(buffer, 0, n);
//                System.out.println(s);
//            }
//        }// 字符流写try (Writer writer=new FileWriter("./test.txt")){String s="你好啊";writer.write(s);}}
}

此处的代码里,有一个关键问题, char 占两个字节,但是我们的汉字是占3个字节(utf8),但是此处读取来的每个字节咋就成2个字节了呢?

此处这个代码,相当于把当前文件的 utf8 在按照字符读取的时候,先转换成 unicode ,每个 char 中存储的是对应的 unicode 的值,如果是基于 unicode 最终还可以构造回 utf8 的 String.

文件utf8 => char[] unicode => String utf8

上述的替换过程我们无法直接感知到, java 里面已经封装好了.

public class IODemo11 {public static void main(String[] args) {try (Writer writer=new FileWriter("./test.txt")){String s="你好啊";writer.write(s);} catch (IOException e) {throw new RuntimeException(e);}}
}

Scanner 也可以辅助我们进行读文件, Scanner(System.in) ,括号内部本质上就是一个 inputStream.

public class IODemo12 {public static void main(String[] args) throws FileNotFoundException {try (InputStream inputStream=new FileInputStream("./test.txt")){Scanner scanner=new Scanner(inputStream);while (scanner.hasNextLine()) {String s=scanner.next();System.out.println(s);}} catch (IOException e) {throw new RuntimeException(e);}}
}

3. 查找硬盘上文件的位置

public class IODemo13 {// 查找硬盘上的文件位置public static void main(String[] args) {Scanner scanner=new Scanner(System.in);System.out.println("请输入文件名: ");String fileName=scanner.next();System.out.println("请输入文件目录: ");String rootPath=scanner.next();File rootFile=new File(rootPath);if (!rootFile.isDirectory()) {System.out.println("输入文件目录有误!");return;}scanDir(fileName,rootFile);}private static void scanDir(String fileName, File rootPath) {File[] files=rootPath.listFiles();if (files==null) {return;}for (File f:files) {//      System.out.println("查找中,当前路径为: "+f.getAbsolutePath());if (f.isDirectory()) {scanDir(fileName,f);}else if (f.isFile()) {if (fileName.equals(f.getName())) {System.out.println("找到了,绝对路径为: "+f.getAbsolutePath());}}else {;}}}
}

此处我们使用递归,就是要进行树的遍历,把目录中,以及其中的子目录,所有的文件都遍历一遍,看是否有符合要求的

4. 实现文件复制

public class IODemo14 {// 复制文件public static void main(String[] args) throws IOException {Scanner scanner=new Scanner(System.in);System.out.println("请输入要复制的源文件: ");String srcPath=scanner.next();System.out.println("请输入要复制的目标文件: ");String destPath=scanner.next();// 检查文件合理性// 1.复制的源文件File srcFile=new File(srcPath);if (!srcFile.isFile()) {System.out.println("源文件路径有误!");return;}// 2.目标文件File destFile=new File(destPath);if (!destFile.getParentFile().isDirectory()) {System.out.println("目标文件路径有误!");return;}try (InputStream inputStream=new FileInputStream(srcPath);OutputStream outputStream=new FileOutputStream(destPath)){while (true) {// 把内容读到inputStreambyte[] buffer=new byte[1024];int n=inputStream.read(buffer);if (n==-1) {break;}// 把内容写到outputStreamoutputStream.write(buffer,0,n);}}}
}

把一个文件复制一下,成为另一个文件,就是把第一个文件读方式打开,一次读取出这里的每个字节,再把读到的内容写入另一个文件里.

3. 在目录中搜索,按照文件内容的方式搜索

public class IODemo15 {public static void main(String[] args) throws IOException {Scanner scanner=new Scanner(System.in);System.out.println("请输入要查找的路径: ");String rootPath=scanner.next();System.out.println("请输入要查找的词: ");String word=scanner.next();// 检查路径合理性File rootFile=new File(rootPath);if (!rootFile.isDirectory()) {System.out.println("查询路径有误!!!");return;}// 开始查找scanDir(word,rootFile);}private static void scanDir(String word, File rootFile) throws IOException {File[] files=rootFile.listFiles();if (files==null) {return;}for (File f:files) {System.out.println("当前遍历到: "+f.getAbsolutePath());// 1.找到对应目录if (f.isFile()) {searchInFile(word,f);}else if (f.isDirectory()) {scanDir(word,f);}else {;}}}private static void searchInFile(String word, File f) throws IOException {try (InputStream inputStream=new FileInputStream(f);){// 拼接字符StringBuilder stringBuilder=new StringBuilder();while (true) {byte[] buffer=new byte[1024];int n=inputStream.read(buffer);if (n==-1) {break;}String string=new String(buffer,0,n);stringBuilder.append(string);}// 字符匹配if (stringBuilder.indexOf(word)!=-1) {System.out.println("找到了"+word+"路径为: "+f.getAbsolutePath());return;}}}
}

用户输入一个目录,一个要搜索的词,遍历文件的过程中没如果文件包含了要搜索的词,此时就把文件的路径打印出来.


相关文章:

【Java EE】文件IO

Author&#xff1a;MTingle major:人工智能 --------------------------------------- Build your hopes like a tower! 目录 一、文件是什么&#xff1f; 二、针对文件系统操作的API 1.文件路径&#xff0c;文件名&#xff0c;文件是否存在 2. 创建文件 3.删除文件&#…...

使用 React、Material-UI、Spring、MySQL、MyBatis 以及高德 API 模拟实时位置信息

要使用 React、Material-UI、Spring、MySQL、MyBatis 以及高德 API 模拟实时位置信息&#xff0c;你可以按以下步骤来实现&#xff1a; 目录 1. 前端 (React Material-UI) 2. 后端 (Spring Boot MyBatis MySQL) 3. 模拟实时位置数据 4. 前后端联调 1. 前端 (React Mat…...

UniApp一句话经验: px -> rpx动态转换和动态元素区域的获取

px->rpx转换 在多终端条件下&#xff0c;什么devicePixelRatio&#xff0c;upx2px都是不靠谱的&#xff0c;最直接的是这样&#xff1a; const { screenWidth } uni.getSystemInfoSync()const pixelUnit screenWidth / 750 // rpx->px比例基数 动态元素区域获取 多终…...

Python基于flask框架的智能停车场车位系统 数据可视化分析系统fyfc81

目录 技术栈和环境说明解决的思路具体实现截图系统设计python语言django框架介绍flask框架介绍性能/安全/负载方面可行性分析论证python-flask核心代码部分展示python-django核心代码部分展示技术路线操作可行性详细视频演示源码获取 技术栈和环境说明 结合用户的使用需求&…...

海外服务器哪个速度最快且性能稳定

海外服务器的速度与性能稳定性受多种因素影响&#xff0c;包括地理位置、网络架构、基础设施质量以及用户网络路径等。在众多选择中&#xff0c;几个特定地区的服务器因其卓越表现而备受推崇。 首先&#xff0c;美国硅谷(加利福尼亚州)与纽约的服务器以其技术领先、网络连接稳定…...

C/C++通过CLion2024进行Linux远程开发保姆级教学

目前来说&#xff0c;对Linux远程开发支持相对比较好的也就是Clion和VSCode了&#xff0c;这两个其实对于C和C语言开发都很友好&#xff0c;大可不必过于纠结使用那个&#xff0c;至于VS和QtCreator&#xff0c;前者太过重量级了&#xff0c;后者更是不用说&#xff0c;主要用于…...

工程师 - 如何安装Windows 终端

Windows 终端是一款适用于 Windows 的现代命令行应用程序&#xff0c;支持多个终端会话&#xff0c;包括 Command Prompt、PowerShell 和 Windows Subsystem for Linux (WSL)。它具有标签式界面、可定制的设置&#xff08;如主题和按键绑定&#xff09;、改进的文本渲染以及对 …...

UniApp 从Vue2升级为Vue3需要注意哪些方面

Vue官方已经发布了Vue3&#xff0c;Vue2不再维护&#xff0c;也在建议大家都迁移到Vue3&#xff0c;所以Vue2终会被淘汰。 那么UniApp 从Vue2升级为Vue3需要注意哪些方面&#xff1a; 1、main.js 下面请看创建应用实例Vue2与Vue3的不同&#xff1a; Vue2的写法&#xff1a;…...

前端面试CSS常见题目

1. CSS 选择器的优先级 (Specificity) 面试官通常会问你如何计算 CSS 选择器的优先级&#xff0c;这对于避免样式冲突、提高代码可维护性很重要。 优先级计算规则&#xff1a; !important 优先级最高。内联样式&#xff08;例如&#xff1a;<div style"color: red;&…...

408算法题leetcode--第10天

643. 子数组最大平均数 I 643. 子数组最大平均数 I思路&#xff1a;滑动窗口时间&#xff1a;O(n)&#xff1b;空间&#xff1a;O(1) class Solution { public:double findMaxAverage(vector<int>& nums, int k) {double ret 0, temp 0;size_t size nums.size()…...

13年计算机考研408-数据结构

解析&#xff1a; 这个降序链表不影响时间复杂度&#xff0c;因为是链表&#xff0c;所以你想要升序就使用头插法&#xff0c;你想要降序就使用尾插法。 然后我们来分析一下最坏的情况是什么样的。 因为m和n都是两个有序的升序序列。 如果刚好m的最大值小于n的最小值&#xff0…...

跨平台开发新视角:利用Android WebView实现Web内容的原生体验

在移动应用开发领域&#xff0c;跨平台解决方案一直是一个热门话题。开发者们不断寻求能够同时在iOS和Android平台上提供一致用户体验的方法。而Android的WebView组件&#xff0c;作为一个强大的工具&#xff0c;允许开发者在Android应用中嵌入Web内容&#xff0c;为用户提供接…...

Stable Diffusion 使用详解(11)--- 场景ICON制作

目录 背景 controlNet 整体描述 Canny Lineart Depth 实际使用 AI绘制需求 绘制过程 PS打底 场景模型选择 设置提示词及绘制参数 controlnet 设置 canny 边缘 depth 深度 lineart 线稿 效果 背景 这段时间不知道为啥小伙伴似乎喜欢制作很符合自己场景的ICON。…...

【Linux系统编程】第二十弹---进程优先级 命令行参数 环境变量

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、进程优先级 2.1、什么是优先级 2.2、优先级的描述 2.3、优先级与权限的关系 2.4、为什么要有优先级 2.5、Linux优先级的…...

无人机之4G模块的主要功能和优势

一、增强图传 在无人机飞行过程中&#xff0c;传统的图传方式可能会受到信号遮挡或干扰的影响&#xff0c;导致图像传输不稳定甚至中断。而4G模块通过结合4G网络技术&#xff0c;能够在原有图传技术的基础上提供增强的图传功能。当传统图传信号不佳时&#xff0c;无人机可以自动…...

深度学习-03 Pytorch

损失函数是用来衡量模型预测结果与真实值之间的差异&#xff0c;并用来优化模型的指标。在机器学习和神经网络中&#xff0c;常用的损失函数包括均方误差&#xff08;Mean Squared Error&#xff0c;MSE&#xff09;、交叉熵&#xff08;Cross-Entropy&#xff09;等。 反向传播…...

GRU(门控循环单元)的原理与代码实现

1.GRU的原理 1.1重置门和更新门 1.2候选隐藏状态 1.3隐状态 2. GRU的代码实现 #导包 import torch from torch import nn import dltools#加载数据 batch_size, num_steps 32, 35 train_iter, vocab dltools.load_data_time_machine(batch_size, num_steps)#封装函数&…...

【医疗大数据】医疗保健领域的大数据管理:采用挑战和影响

选自期刊**《International Journal of Information Management》**&#xff08;IF:21.0) 医疗保健领域的大数据管理&#xff1a;采用挑战和影响 1、研究背景 本研究的目标是调查阻止医疗机构实施成功大数据系统的组织障碍&#xff0c;识别和评估这些障碍&#xff0c;并为管理…...

gevent + flask 接口会卡住

在使用 gevent 和 Flask 处理 CPU 密集型任务时&#xff0c;确实可能会遇到性能瓶颈。这是因为 gevent 主要优化的是 I/O 密集型任务&#xff0c;而不是 CPU 密集型任务。以下是一些可能的原因和解决方案&#xff1a; 原因 Gevent 的协程模型&#xff1a; gevent 使用 greenle…...

SpringCloud Alibaba五大组件之——Sentinel

SpringCloud Alibaba五大组件之——Sentinel&#xff08;文末附有完整项目GitHub链接&#xff09; 前言一、什么是Sentinel二、Sentinel控制台1.下载jar包2.自己打包3.启动控制台4.浏览器访问 三、项目中引入Sentinel1.在api-service模块的pom文件引入依赖&#xff1a;2.applic…...

brpc之io事件分发器

结构 #mermaid-svg-v4SjrdGXadMO4udP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-v4SjrdGXadMO4udP .error-icon{fill:#552222;}#mermaid-svg-v4SjrdGXadMO4udP .error-text{fill:#552222;stroke:#552222;}#merm…...

MySQL | 知识 | 从底层看清 InnoDB 数据结构

文章目录 一、InnoDB 简介InnoDB 行格式COMPACT 行格式CHAR(M) 列的存储格式VARCHAR(M) 最多能存储的数据记录中的数据太多产生的溢出行溢出的临界点 二、表空间文件的结构三、InnoDB 数据页结构页页的概览Infimum 和 Supremum使用Page Directory页的真实面貌 四、B 树是如何进…...

es的封装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、类和接口介绍0.封装思想1.es的操作分类 二、创建索引1.成员变量2.构造函数2.添加字段3.发送请求4.创建索引总体代码 三.插入数据四.删除数据五.查询数据 前…...

写一个自动化记录鼠标/键盘的动作,然后可以重复执行的python程序

import sys import threading import time from PyQt5.QtWidgets import * from auto_fun import * import pyautogui import pynput from PyQt5.QtCore import pyqtSignal from MouseModule import * from pynput import keyboardlocal_list [] # 保存操作坐标、动作、文本 …...

Spring Boot-热部署问题

Spring Boot 热部署问题分析与解决方案 热部署&#xff08;Hot Deployment&#xff09;是指在应用程序运行过程中&#xff0c;无需停止应用就可以动态加载新代码、配置或资源&#xff0c;从而提升开发效率。在 Spring Boot 开发中&#xff0c;热部署是一项非常实用的功能&…...

深度学习——管理模型的参数

改编自李沐老师《动手深度学习》5.2. 参数管理 — 动手学深度学习 2.0.0 documentation (d2l.ai) 在深度学习中&#xff0c;一旦我们选择了模型架构并设置了超参数&#xff0c;我们就会进入训练阶段。训练的目标是找到能够最小化损失函数的模型参数。这些参数在训练后用于预测&…...

芯片验证板卡设计原理图:372-基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台

基于XC7VX690T的万兆光纤、双FMC扩展的综合计算平台 RISCV 芯片验证平台 一、板卡概述 基于V7的高性能PCIe信号处理板&#xff0c;北京太速科技板卡选用Xilinx 公司Virtex7系列FPGA XC7VX690T-2FFG1761C为处理芯片&#xff0c;板卡提供两个标准FMC插槽&#xff0c;适用于…...

【软设】 系统开发基础

【软设】 系统开发基础 一.软件工程概述 &#xff08;了解一下大概的流程就行&#xff09; 1. 可行性分析与项目开发计划 目的&#xff1a;评估项目的经济性、技术性和运营性&#xff0c;判断项目是否值得投资和开发。确定开发时间、预算、所需资源等。 可行性分析&#xff…...

Linux移植之系统烧写

直接参考【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81 本文仅作为个人笔记使用&#xff0c;方便进一步记录自己的实践总结。 前面我们已经移植好了 uboot 和 linux kernle&#xff0c;制作好了根文件系统。但是我们移植都是通过网络来测试的&#xff0c;在实际的产品开发中…...

【数据结构与算法】LeetCode:双指针法

文章目录 LeetCode&#xff1a;双指针法正序同向而行&#xff08;快慢指针&#xff09;移除元素移动零&#xff08;Hot 100&#xff09;删除有序数组中的重复项颜色分类&#xff08;Hot 100&#xff09;压缩字符串移除链表元素删除排序链表中的重复元素删除排序链表中的重复元素…...