[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等…...

vue : 无法加载文件 C:\Users\jianfei\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。...
背景 在新电脑上配置vue环境 PS E:\CODE_PROJ\myvue\vue23\P61_使用脚手架\vue_test> npm install -g vue/cli npm WARN deprecated source-map-url0.4.1: See https://github.com/lydell/source-map-url#deprecated npm WARN deprecated urix0.1.0: Please see https://git…...

godot引擎c++源码深度解析系列二
记录每次研究源码的突破,今天已经将打字练习的功能完成了一个基本模型,先来看下运行效果。 godot源码增加打字练习的demo 这个里面需要研究以下c的控件页面的开发和熟悉,毕竟好久没有使用c了,先来看以下代码吧。 //第一排 显示文本…...

专才or 通才
前言 不知道大家有没有这样的感觉,现在的工作专业化程度越来越高,而且是细分方向越来越小。IT领域分到你是计算里面的数据库或者了流式计算引擎,或者是协议存储还是KV存储引擎。 专业化的优势 专业化的程度带来了一个好处就是你在这个领域…...

【小白必看】Python爬虫实战之批量下载女神图片并保存到本地
文章目录 前言运行结果部分图片1. 引入所需库2. 发送请求获取网页内容3. 解析网页内容并提取图片地址和名称4. 下载并保存图片完整代码关键代码讲解 结束语 前言 爬取网络上的图片是一种常见的需求,它可以帮助我们批量下载大量图片并进行后续处理。本文将介绍如何使…...

道本科技||全面建立国有企业合规管理体系
为全面深化国有企业法治建设,不断加强合规管理,防控合规风险,保障企业稳健发展,近日,市国资委印发《常州市市属国有企业合规管理办法(试行)》(以下简称《办法》)…...

CentOS 8上安装和配置Redis
在本篇博客中,我们将演示如何在CentOS 8上安装和配置Redis。我们将首先安装Redis,然后配置Redis以设置密码并允许公开访问。 步骤 1:安装Redis 首先,更新软件包列表: sudo yum update安装Redis: sudo yum …...

西北乱跑娃 -- CSS动态旋转果冻效果
<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>旋转果冻</title> <style> #myDIV {margin: 250px;width: 250px;height: 250px;background: orange;position: relative;font-size: 20px;animation: anima…...

解决安装office出现1402错误和注册表编辑器无法设置安全性错误
写在前面 可能是由于之前的office没有卸载干净,看了很多文章,也有的说是使用了Windows Installer Clean Up卸载office的缘故,最后导致的结果是出现了再次安装office时出现了1402错误,而在解决1402错误的过程中,修改所…...

Jmeter接口自动化生成测试报告html格式
jmeter自带执行结果查看的插件,但是需要在jmeter工具中才能查看,如果要向领导提交测试结果,不够方便直观。 笔者刚做了这方面的尝试,总结出来分享给大家。 这里需要用到ant来执行测试用例并生成HTML格式测试报告。 一、ant下载安…...

移动IP的原理
目的 使得移动主机在各网络之间漫游时,仍然能保持其原来的IP地址不变 工作步骤 代理发现与注册 主机A:主机A移动到外地网络后,通过“代理发现协议”,与外地代理建立联系,并从外地代理获得一个转交地址,…...