[JAVAee]文件操作-IO
本文章讲述了通过java对文件进行IO操作
IO:input/output,输入/输出.
建议配合文章末尾实例食用
目录
文件
文件的管理
文件的路径
文件的分类
文件系统的操作
File类的构造方法
File的常用方法
文件内容的读写
FileInputStream读取文件
构造方法
常用方法
Scanner读取
FileOutputStream写入文件
PrintfWriter写入
关于close()方法
文件操作示例
根据文件名搜索并删除文件
文件的复制
根据文件内容或文件名搜索
文件
针对硬盘来说,会将存储的数据分成一个一个独立的单位进行保存,这个独立的单位就被抽象的称为"文件".
我们平时的文件都是存储在硬盘当中的.
文件的管理
随着存储的数据增多,对于这些数据也会进行一定的管理.
对于文件,我们会进行层级管理,也就是数据结构中的树形结构.就这样,出现了一种管理文件的特殊文件:目录(directory)也就是俗称的文件夹.
文件的路径
路径(path)是一个文件在系统中的具体位置.
从树形结构来看,就是由上到下的从一个根节点开始描述到目标文件.
路径的表示:从盘符开始,用"\"或"/"分割开(在Windows中一般都从"此电脑"开始,表示的时候可以将其忽略)
路径根据"基准目录"的不同,又可以分为:
- 绝对路径:从盘符开始往下遍历直到目标文件,所得到的路径
- 相对路径:从指定的目录开始往下遍历直到目标文件,所得到的路径
C:\Program Files\Java\jdk1.8.0_192(绝对目录)
\Java\jdk1.8.0_192(相对目录)
在windows系统上,一个文件的路径是绝对唯一的,可以说文件与路径一一对应的.
文件的分类
根据所保存的数据的不同,文件可以被分为:
二进制文件:按照标志格式保存的没被字符集编码过的文件
文本文件:存储被字符集编码过的文本
文件系统的操作
在JAVA的标准库当中,提供了File这个类.
此处的File实例化出的对象是硬盘上一个文件或目录的抽象表示.
File类的构造方法
构造方法中的路径指定的文件可以是存在的,也可以是不存在的.
File(File parent, String child) 通过父亲抽象路径名与子抽象路径名创建一个File实例 |
File(String pathname) 通过转换传输的路径名字符串转化成为抽象路径名来创建File实例 |
File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的 File实例。 |
File(URI uri) 通过将给定的 file: URI转换为抽象路径名来创建新的 File实例。 |
File的常用方法
这些方法的作用都能很清楚的明白,就不再一一演示了.
| 修饰符及返回 值类型 | 方法 | 说明 |
| String | getParent() | 返回 File 对象的父目录文件路径 |
| String | getName() | 返回 FIle 对象的纯文件名称 |
| String | getPath() | 返回 File 对象的文件路径 |
| String | getAbsolutePath() | 返回 File 对象的绝对路径 |
| String | getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
| boolean | exists() | 判断 File 对象描述的文件是否真实存在 |
| boolean | isDirectory() | 判断 File 对象代表的文件是否是一个目录 |
| boolean | isFile() | 判断 File 对象代表的文件是否是一个普通文件 |
| boolean | createNewFile() | 根据 File 对象,自动创建一个空文件。成功创建后返 回 true |
| boolean | delete() | 根据 File 对象,删除该文件。成功删除后返回 true |
| void | deleteOnExit() | 根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行 |
| String[] | list() | 返回 File 对象代表的目录下的所有文件名 |
| File[] | listFiles() | 返回 File 对象代表的目录下的所有文件,以 File 对象 表示 |
| boolean | mkdir() | 创建 File 对象代表的目录 |
| boolean | mkdirs() | 创建 File 对象代表的目录,如果必要,会创建中间目 录 |
| boolean | renameTo(File dest) | 进行文件改名,也可以视为我们平时的剪切、粘贴操 作 |
| boolean | canRead() | 判断用户是否对文件有可读权限 |
| boolean | canWrite() | 判断用户是否对文件有可写权限 |
如果放入的是绝对路径
public static void main(String[] args) throws IOException {File file = new File("D:\\tools\\TMP");System.out.println(file.getParent());System.out.println(file.getName());System.out.println(file.getPath());System.out.println(file.getAbsolutePath());System.out.println(file.getCanonicalPath());}

放入的是相对路径.
当调用打印绝对路径与相对路径的时候会根据当前所在的工作目录创建.
这时候,文件是并不存在的.调用createNewFile()才会创建新的文件.
File file = new File(".\\TMP");

文件内容的读写
针对文件内容的操作,会使用到"流"来操作.
流,从字面意思上可以看作为"水流",是可以随心所读的读写的.对于读取数据,可以一次读取1个字节,5个字节,10个字节也可以一次性读完100个字节.相反,对于写入数据来说,也是一样的.这些数据不会被限制一次只能读取一定量或被捆绑在一起.
因此,就把读写文件相关的对象,成为"流对象".
在java标准库的流对象,从类型上可以分成两大类:
- 字节流对象:InputStream,OutputStream...(可以读取文本文件与二进制文件)
- 字符流对象:Reader,Writer...(只能读取文本文件)
在此处的输入与输出,是以CPU为基准的:
Input是从CPU向硬盘输入,达到读取文件的效果.
Output是从CPU向硬盘输出,达到写入文件的效果.

FileInputStream读取文件
上面介绍的字节流对象的InputStream只是一个抽象类,对于文件的IO来说.使用其中一个实现类FileInputStream就可以了
构造方法
| 方法 | 说明 |
| FileInputStream(File file) | 利用 File 构造文件输入流 |
| FileInputStream(String name) | 利用文件路径构造文件输入流 |
//构造方法1
File file = new File("D:/tools/TMP/book.txt");
FileInputStream inputStream = new FileInputStream(file);
//构造方法2
FileInputStream inputStream1 = new FileInputStream("D:/tools/TMP/book.txt");
常用方法
| 修饰符及 返回值类 型 | 方法 | 说明 |
| int | read() | 读取一个字节的数据,返回 -1 代表已经完全读完了 |
| int | read(byte[] b) | 最多读取 b.length 字节的数据到 b 中,返回实际读到的数 量;-1 代表以及读完了 |
| int | read(byte[] b, int off, int len) | 最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返 回实际读到的数量;-1 代表以及读完了 |
| void | close() | 关闭字节流 |
无参数read
while(true){int n = inputStream.read();if(n == -1){break;}System.out.printf("%c",n);//%c是字符型格式符,以字符为单位进行输出.直接输出会得到的是ASCII码}inputStream.close();//释放资源
byte[]参数read(更推荐使用此方法)
带有数组参数的read能够极大的减少对文件的IO次数,减少了发生异常的可能.
byte[] buf = new byte[1024];//数组的长度为一次读取的字节数while(true){ //数组的长度不能一次读完字节,下一次的读取就会覆盖上一次的数据int len;len = inputStream.read(buf);if(len == -1){break;}for(int i = 0; i < len; i++){System.out.println(buf[i]);}}inputStream.close();//释放资源
Scanner读取
将FileInputStream套上一个Scanner更方便的操作
| 构造方法 | 说明 |
| Scanner(InputStream is, String charset) | 使用 charset 字符集进行 is 的扫描读取 |
Scanner scanner = new Scanner(inputStream,"UTF_8");while(scanner.hasNext()){String s = scanner.next();System.out.println(s);}scanner.close();
FileOutputStream写入文件
构造方法与FileInputStream是基本相同的.
| 返回 值类 型 | 方法签名 | 说明 |
| void | write(int b) | 写入要给字节的数据 |
| void | write(byte[] b) | 将 b 这个字符数组中的数据全部写入 os 中 |
| int | write(byte[] b,int off, int len) | 将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个 |
| void | close() | 关闭字节流 |
| void | flush() | 刷新此输出流并强制任何缓冲的输出字节被写出 |
- 关于flush方法,计算机为了减少I/O的次数.在写入数据的时候,先会把数据放入到缓冲区当中.如果数据特别小的,可能还在缓冲区中.未能及时的放到文件当中,其他流可能就会读取不到.
FileOutputStream outputStream = new FileOutputStream("D:/tools/TMP/book.txt");outputStream.write('H');//单个字符byte[] arr = {(byte) 'E',(byte) 'L'};//byte[]outputStream.write(arr);String s = "LO";byte[] arr2 = s.getBytes("UTF-8");//将字符串转换成"UTF-8"字符集的字符放入byte[]outputStream.write(arr2);outputStream.flush();//刷新缓冲区outputStream.close();
写入后,会覆盖原有的数据.
PrintfWriter写入
FileOutputStream outputStream = new FileOutputStream("D:/tools/TMP/book.txt");
PrintWriter writer = new PrintWriter(outputStream);
writer.println("hello");
writer.flush();
writer.close();
outputStream.close();
关于close()方法
前面介绍了进程,关于进程会用PCB来进行描述
而PCB里又包括了:
- pid
- 内存指针
- 文件描述符
对于close,我们释放的主要是文件描述符.其记载了在此进程中,打开了什么文件,关闭了什么文件或正在使用什么文件等.就像一个数组一样,每进行一个操作会占上一个下标,但表的长度有限,可能会被完全占满.一旦占满了不进行释放,再继续打开文件就会发生错误,可能造成文件资源泄露的问题.
除了直接的使用close方法释放资源,还可以使用相应的带有资源的try方法.
这样就不怕忘记使用close方法了
try(FileInputStream inputStream1 = new FileInputStream("D:/tools/TMP/book.txt")){byte[] buf = new byte[1024];while(true){int len;len = inputStream.read(buf);if(len == -1){break;}for(int i = 0; i < len; i++){System.out.println(buf[i]);}}}
文件操作示例
根据文件名搜索并删除文件
主要思路是:
- 遍历当前的目录,如果遍历到的文件是一个目录继续递归遍历
- 如果是一个普通文件,则判断是否为我们要找的文件
public static Scanner scanner = new Scanner(System.in);public static void main(String[] args) {//输入要搜索的目录//判断目录是否存在//输入要删除的文件名//遍历目录,搜索文件是否存在System.out.println("请输入要搜素的根目录的路径");String dirName = scanner.next();File dir = new File(dirName);//创建目录实例if(!dir.isDirectory()){//判断是否为目录System.out.println("输入的路径并非根目录,或根目录不存在");return;}System.out.println("输入要删除的文件的关键字");String keyName = scanner.next();scanner(dir,keyName);}public static void scanner(File dir,String keyName){File[] files = dir.listFiles();//此方法,将dir当中的文件存储到File[]中if(files == null){return;//证明这个目录下没有东西了}//如果目录下还有东西,就将他遍历一遍for (File f: files) {if(f.isDirectory()){//如果还是目录,递归遍历里面的文件scanner(f,keyName);}else{//如果是普通文件,判断是否带有关键字if(f.getName().contains(keyName)){//如果带有关键字System.out.println("输入\"YES\"来确认是否要删除: " + f.getAbsolutePath());System.out.println("输入任意其他取消删除");String s = scanner.next();if(s.equals("YES")){System.out.println(f.delete());}else{System.out.println("取消");}}}}}

文件的复制
主要思路:
- 判断被复制的文件在不在或者是否为一个普通文件
- 判断要去的路径存不存在被复制的文件
- 从被复制的文件进行读操作,再进行写操作写入到目标处
public static void main(String[] args) {//判断被复制的文件在不在或者是否为一个普通文件//判断要去的路径存不存在被复制的文件//从被复制的文件进行读操作,再进行写操作写入到目标处Scanner scanner = new Scanner(System.in);System.out.println("输入要复制的文件的路径");String source = scanner.next();//要复制的文件File sourFile = new File(source);if(!sourFile.isFile()){//判断是否为一个普通文件,同时也判断了其是否存在System.out.println("路径错误,目标无法复制");return;}System.out.println("输入要复制到的路径");String dir = scanner.next();File dirFile = new File(dir);//要复制去的路径if(dirFile.isFile()){//如果已经有了文件,则不进行复制System.out.println("文件已存在或路径错误");return;}//进行读写操作//使用带资源的try,最后会自动释放资源try(InputStream inputStream = new FileInputStream(sourFile); OutputStream outputStream = new FileOutputStream(dirFile)) {byte[] buf = new byte[1024];while(true){int len = inputStream.read(buf);if(len == -1){System.out.println("复制完毕");break;}outputStream.write(buf);}} catch (IOException e) {e.printStackTrace();}}

根据文件内容或文件名搜索(简单版)
//遍历目录,读取普通文件的内容与关键字进行匹配//如果是目录则递归遍历public static List<File> ret = new ArrayList<>();public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("输入要搜索的目录路径");String s = scanner.next();File sFile = new File(s);if(!sFile.isDirectory()){System.out.println("输入的路径有误");return;}System.out.println("输入关键字");String keyName = scanner.next();scan(sFile,keyName);System.out.println("相关搜索的文件有");for (File f:ret) {System.out.println(f.getAbsolutePath());}}public static void scan(File root,String keyName){File[] files = root.listFiles();//得到当前目录的所有文件if(files == null){//递归结束的条件return;}for (File f:files) {if(f.isDirectory()){//如果是目录//继续递归scan(f,keyName);}else{//如果是普通文件//判断文件名是否存在关键字//判断内容是否存在关键字//如果满足其一,则放到列表中if(isContainOnName(f,keyName) || isContainOnContent(f,keyName)){ret.add(f);}}}}public static boolean isContainOnName(File file,String keyName){return file.getName().contains(keyName);}public static boolean isContainOnContent(File file,String keyName){//进行读操作//组成一个字符串,判断keyName是否存在字符串中//当然这种方法有点蠢,性能非常差.不要用于大文件当中StringBuffer buffer = new StringBuffer();try(InputStream inputStream = new FileInputStream(file);Scanner scan = new Scanner(inputStream,"UTF-8")){while(scan.hasNext()){buffer.append(scan.next());}} catch (IOException e) {e.printStackTrace();}return buffer.indexOf(keyName) != -1;//StringBuffer没有contains可以用indexOf,如果返回值为-1代表无子串}
相关文章:
[JAVAee]文件操作-IO
本文章讲述了通过java对文件进行IO操作 IO:input/output,输入/输出. 建议配合文章末尾实例食用 目录 文件 文件的管理 文件的路径 文件的分类 文件系统的操作 File类的构造方法 File的常用方法 文件内容的读写 FileInputStream读取文件 构造方法 常用方法 Scan…...
【数据集】3小时尺度降水数据集-MSWEPV2
1 MSWEP V2 precipitation product 官网-MSWEP V2降水产品 参考...
Springboot之把外部依赖包纳入Spring容器管理的两种方式
前言 在Spring boot项目中,凡是标记有Component、Controller、Service、Configuration、Bean等注解的类,Spring boot都会在容器启动的时候,自动创建bean并纳入到Spring容器中进行管理,这样就可以使用Autowired等注解,…...
更安全,更省心丨DolphinDB 数据库权限管理系统使用指南
在数据库产品使用过程中,为保证数据不被窃取、不遭破坏,我们需要通过用户权限来限制用户对数据库、数据表、视图等功能的操作范围,以保证数据库安全性。为此,DolphinDB 提供了具备以下主要功能的权限管理系统: 提供用户…...
WPS本地镜像化在线文档操作以及样例
一个客户项目有引进在线文档操作需求,让我这边做一个demo调研下,给我的对接文档里有相关方法的说明,照着对接即可。但在真正对接过程中还是踩过不少坑,这儿对之前的对接工作做个记录。 按照习惯先来一个效果: Demo下载…...
STM32 Flash学习(一)
STM32 FLASH简介 不同型号的STM32,其Flash容量也不同。 MiniSTM32开发板选择的STM32F103RCT6的FLASH容量为256K字节,属于大容量产品。 STM32的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等3部分组成。 主存储器,该部分…...
Spring中IOC容器常用的接口和具体的实现类
在Spring框架没有出现之前,在Java语言中,程序员们创建对象一般都是通过关键字new来完成,那时流行一句话“万物即可new,包括女朋友”。但是这种创建对象的方式维护成本很高,而且对于类之间的相互关联关系很不友好。鉴于…...
【MySQL】索引特性
🌠 作者:阿亮joy. 🎆专栏:《零基础入门MySQL》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录 👉没…...
【深度学习笔记】动量梯度下降法
本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记,视频由网易云课堂与 deeplearning.ai 联合出品,主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习,视频的链接如下: 神经网络和…...
《TCP IP网络编程》第十二章
第 12 章 I/O 复用 12.1 基于 I/O 复用的服务器端 多进程服务端的缺点和解决方法: 为了构建并发服务器,只要有客户端连接请求就会创建新进程。这的确是实际操作中采用的一种方案,但并非十全十美,因为创建进程要付出很大的代价。…...
基于CNN卷积神经网络的调制信号识别算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 卷积神经网络(CNN) 2. 调制信号识别 3.实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 % 构建调制类型…...
正则,JS:this,同步异步,原型链笔记整理
一 正则表达式 正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本 正则表达式可以用于以下常见操作: 匹配&…...
【NOIP】小鱼的数字游戏题解
author:&Carlton tag:递归,栈 topic:【NOIP】小鱼的数字游戏题解 language:C website:洛谷 date:2023年7月29日 目录 我的题解思路 优化 别人的优秀思路: 我的题解思路 题…...
算法的时间复杂度、空间复杂度如何比较?
目录 一、时间复杂度BigO 大O的渐进表示法: 例题一: 例题2: 例题3:冒泡排序的时间复杂度 例题4:二分查找的时间复杂度 书写对数的讲究: 例题5: 实例6: 利用时间复杂度解决编…...
We are the Lights 2023牛客暑期多校训练营4-L
登录—专业IT笔试面试备考平台_牛客网 题目大意:有n*m盏灯,q次操作,每次可以将一整行或一整列的等打开或关闭 1<n,m<1e6;1<q<1e6 思路:对于同一行或者同一列来说,只要最后一次操作时开或者关࿰…...
ant-design-vue中table组件使用customRender渲染v-html
ant-design-vue遇到table中列表数据需要高亮渲染 1、customRender可以使用,但是使用v-html发现不生效还报错 const columns [title: name,dataIndex: name,customRender: (val, row) > {return <span v-html{val}></span>} ]2、customeRender函数…...
若依框架实现后端防止用户重复点击
若依框架实现后端防止用户重复点击 基于自定义注解、切面、Redis实现 1. 添加自定义注解: 代码放置位置:com/ruoyi/common/annotation/RepeatClick.java time: 时间默认0; unit:单位默认 秒; key: 默认空字符串 package com.ruoyi.fra…...
PCA对手写数字数据集的降维
手写数字的数据集结构为(42000, 784),用KNN跑一次半小时,得到准确率在96.6%上下,用随机森林跑一次12秒,准确率在93.8%,虽然KNN效果好,但由于数据量太大,KNN计算太缓慢,所以我们不得不选用随机森林。我们使用了各种技术对手写数据集进行特征选择,最后使用嵌入 法Select…...
Python入门【变量的作用域(全局变量和局部变量)、参数的传递、浅拷贝和深拷贝、参数的几种类型 】(十一)
👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…...
下级平台级联安防视频汇聚融合EasyCVR平台,层级显示不正确是什么原因?
视频汇聚平台安防监控EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
DiscuzX3.5发帖json api
参考文章:PHP实现独立Discuz站外发帖(直连操作数据库)_discuz 发帖api-CSDN博客 简单改造了一下,适配我自己的需求 有一个站点存在多个采集站,我想通过主站拿标题,采集站拿内容 使用到的sql如下 CREATE TABLE pre_forum_post_…...
