[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的常用方法

这些方法的作用都能很清楚的明白,就不再一一演示了.

修饰符及返回
值类型
方法说明
StringgetParent()返回 File 对象的父目录文件路径
StringgetName()返回 FIle 对象的纯文件名称
StringgetPath()返回 File 对象的文件路径
StringgetAbsolutePath()返回 File 对象的绝对路径
StringgetCanonicalPath()返回 File 对象的修饰过的绝对路径
booleanexists()判断 File 对象描述的文件是否真实存在
booleanisDirectory()判断 File 对象代表的文件是否是一个目录
booleanisFile()判断 File 对象代表的文件是否是一个普通文件
booleancreateNewFile()根据 File 对象,自动创建一个空文件。成功创建后返
回 true
booleandelete()根据 File 对象,删除该文件。成功删除后返回 true
voiddeleteOnExit()根据 File 对象,标注文件将被删除,删除动作会到
JVM 运行结束时才会进行
String[]list()返回 File 对象代表的目录下的所有文件名
File[]listFiles()返回 File 对象代表的目录下的所有文件,以 File 对象
表示
booleanmkdir()创建 File 对象代表的目录
booleanmkdirs()创建 File 对象代表的目录,如果必要,会创建中间目
booleanrenameTo(File
dest)
进行文件改名,也可以视为我们平时的剪切、粘贴操
booleancanRead()判断用户是否对文件有可读权限
booleancanWrite()判断用户是否对文件有可写权限

如果放入的是绝对路径 

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");

常用方法

修饰符及
返回值类
方法说明
intread()读取一个字节的数据,返回 -1 代表已经完全读完了
intread(byte[] b)最多读取 b.length 字节的数据到 b 中,返回实际读到的数
量;-1 代表以及读完了
intread(byte[] b,
int off, int len)
最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返
回实际读到的数量;-1 代表以及读完了
voidclose()关闭字节流

无参数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是基本相同的.

返回
值类
方法签名说明
voidwrite(int b)写入要给字节的数据
voidwrite(byte[] b)将 b 这个字符数组中的数据全部写入 os 中
int

write(byte[] b,int off,

int len)

将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个
voidclose()关闭字节流
voidflush()

刷新此输出流并强制任何缓冲的输出字节被写出

  • 关于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代表无子串}

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

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

相关文章

平均列顺序对列排斥能的影响

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) 让网络的输入只有3个节点&#xff0c;AB训练集各由5张二值化的图片组成&#xff0c;让A有6个1&#xff0c;B有4个1&#xff0c;并且让这10个1的位置没有重合。比较迭代次数的顺序。 其中有9组数据 差值结构 A-B 迭代次数 构造平均列 …

使用PyGWalker可视化分析表格型数据

大家好&#xff0c;可以想象一下在Jupyter Notebook中拥有大量数据&#xff0c;想要对其进行分析和可视化。PyGWalker就像一个神奇的工具&#xff0c;能让这项工作变得超级简单。它能获取用户的数据&#xff0c;并将其转化为一种特殊的表格&#xff0c;可以与之交互&#xff0c…

ES6 - promise.all和race方法的用法详解

文章目录 一、前言二、Promise.all()1&#xff0c;第一句&#xff1a;Promise.all()方法接受一个数组作为参数&#xff0c;且每一个都是 Promise 实例2&#xff0c;第二句&#xff1a;如果不是&#xff0c;就会先调Promise.resolve方法&#xff0c;将参数转为 Promise 实例再进…

pytorch的发展历史,与其他框架的联系

我一直是这样以为的&#xff1a;pytorch的底层实现是c(这一点没有问题&#xff0c;见下边的pytorch结构图),然后这个部分顺理成章的被命名为torch,并提供c接口,我们在python中常用的是带有python接口的&#xff0c;所以被称为pytorch。昨天无意中看到Torch是由lua语言写的&…

【如何训练一个中英翻译模型】LSTM机器翻译模型部署(三)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何训…

Windows Server 2012 能使用的playwright版本

由于在harkua_bot里面使用到了playwright&#xff0c;我的服务器又是Windows Server 2012 R2&#xff0c;最新版playwright不支持Windows Server 2012 R2&#xff0c;支持Windows Server 2016以上&#xff0c;所以有了这个需求 https://cdn.npmmirror.com/binaries/playwright…

Hadoop生态体系-HDFS

目录标题 1、Apache Hadoop2、HDFS2.1 设计目标&#xff1a;2.2 特性&#xff1a;2.3 架构2.4 注意点2.5 HDFS基本操作2.5.1 shell命令选项2.5.2 shell常用命令介绍 3、HDFS基本原理3.1 NameNode 概述3.2 Datanode概述 1、Apache Hadoop Hadoop&#xff1a;允许使用简单的编程…

Android Hook 剪切板相关方法

想起之前做过的项目有安全合规要求&#xff1a;主动弹窗获取用户同意了才能调用剪切板相关方法&#xff0c;否则属于违规调用&#xff0c;如果是自己项目的相关调用可以自己加一层if判断 但是一些第三方的jar包里面也有在调用的话&#xff0c;我们就无能为力了&#xff0c;而且…

JPA连接达梦数据库导致auto-ddl失效问题解决

现象&#xff1a; 项目使用了JPA&#xff0c;并且auto-ddl设置的为update&#xff0c;在连接达梦数据库的时候&#xff0c;第一次启动没有问题&#xff0c;但是后面重启就会报错&#xff0c;发现错误为重复建表&#xff0c;也就是说已经建好的表没有检测到&#xff0c;…

JVM类加载

一、类记载过程 1、通过类的全限定名获取存储该类的class文件 2、解析成运行时数据&#xff0c;即instanceKlass实例&#xff0c;存放到方法区 3、在堆区生成该类的class对象,即instanceMirrorKlass实例 二、将.class文件解析成什么&#xff1f;类的元信息在JVM中如何…

ceph集群中RBD的性能测试、性能调优

文章目录 rados benchrbd bench-write测试工具Fio测试ceph rbd块设备的iops性能测试ceph rbd块设备的带宽测试ceph rbd块设备的延迟 性能调优 rados bench 参考&#xff1a;https://blog.csdn.net/Micha_Lu/article/details/126490260 rados bench为ceph自带的基准测试工具&am…

全加器(多位)的实现

一&#xff0c;半加器 定义 半加器&#xff08;Half Adder&#xff09;是一种用于执行二进制数相加的简单逻辑电路。它可以将两个输入位的和&#xff08;Sum&#xff09;和进位&#xff08;Carry&#xff09;计算出来。 半加器有两个输入&#xff1a;A 和 B&#xff0c;分别代表…

MySQL基础扎实——MySQL中有那些不同的表格

表格类型 在MySQL中&#xff0c;常见的表格类型有以下几种&#xff1a; MyISAM&#xff1a;是MySQL默认的表格类型&#xff0c;具有较高的性能和较小的存储空间占用。但是&#xff0c;MyISAM不支持事务、崩溃恢复和数据行级锁定。 InnoDB&#xff1a;是MySQL提供的一个更强大…

Redis实现分布式锁

文章目录 4、分布式锁4.1 、基本原理和实现方式对比4.2 、Redis分布式锁的实现核心思路4.3 实现分布式锁版本一4.4 Redis分布式锁误删情况说明4.5 解决Redis分布式锁误删问题4.6 分布式锁的原子性问题4.7 Lua脚本解决多条命令原子性问题4.8 利用Java代码调用Lua脚本改造分布式锁…

MySQL | 常用命令示例

MySQL | 常用命令示例 一、启停MySQL数据库服务二、连接MySQL数据库三、创建和管理数据库四、创建和管理数据表五、数据备份和恢复六、查询与优化 MySQL是一款常用的关系型数据库管理系统&#xff0c;广泛应用于各个领域。在使用MySQL时&#xff0c;我们经常需要编写一些常用脚…

【数据结构】【王道408】——PPT截图与思维导图

自用视频PPT截图 视频网址王道B站链接 23考研 408新增考点&#xff1a; 并查集&#xff0c;红黑树 2023年408真题数据结构篇 408考纲解读 考纲变化 目录 第一章 绪论第二章 线性表顺序表单链表双链表循环链表静态链表差别 第三章 栈 队列 数组栈队列栈的应用数组 第四章 串第五…

软考A计划-系统集成项目管理工程师-项目质量管理-中

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

小程序UV:衡量用户规模与活跃度的重要指标

什么是UV UV是Unique Visitor&#xff08;独立访客&#xff09;的缩写&#xff0c;指的是在特定时间段内访问某个网站、应用或平台的独立用户数量。UV是根据设备、IP地址、Cookie等来识别不同的用户&#xff0c;对于相同的用户多次访问&#xff0c;只计算为一个UV。UV是衡量网…

流数据湖平台Apache Paimon(一)概述

文章目录 第1章 概述1.1 简介1.2 核心特性1.3 基本概念1.3.1 Snapshot1.3.2 Partition1.3.3 Bucket1.3.4 Consistency Guarantees一致性保证 1.4 文件布局1.4.1 Snapshot Files1.4.2 Manifest Files1.4.3 Data Files1.4.4 LSM Trees 第1章 概述 1.1 简介 Flink 社区希望能够将…

RocketMQ重复消费的解决方案::分布式锁直击面试!

文章目录 场景分析方法的幂等分布式锁Redis实现分布式锁抢锁的设计思路 分布式锁案例 直击面试rocketmq什么时候重复消费消息丢失的问题消息在哪里丢失发送端确保发送成功并且配合失败的业务处理消费端确保消息不丢失rocketmq 主从同步刷盘 场景分析 分布式系统架构中,队列是分…