文件操作IO

文件操作IO

  • .
  • 认识文件
  • 树型结构组织 和 目录
  • 文件路径(Path)
  • 其他知识
  • Java 中操作文件
    • 构造方法
    • 方法
  • 创建文件
  • 删除文件
  • 创建目录
  • 重命名
  • 文件内容的读写 —— 数据流
    • Reader/Writer(字符流)
    • InputStream/OutputStreadm(字节流)
      • scanner
  • 例题
    • 1.扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要
    • 2.进行普通文件的复制

.

在这里插入图片描述

认识文件

我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的I/O设备,当我们想要进行数据保存时,往往不是保存成一个整体,而是独立成一个个的单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌上的一份份真实的文件一般
文件除了有数据内容之外,还有一部分信息,例如文件名、文件类型、文件大小等并不作为文件的数据而存在,我们把这部分信息可以视为文件的元信息

树型结构组织 和 目录

同时,随着文件越来越多,对文件的系统管理也被提上了日程,如何进行文件的组织呢,一种合乎自然的想法出现了,就是按照层级结构进行组织 —— 也就是我们数据结构中学习过的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory)的概念。

文件路径(Path)

如何在文件系统中如何定位我们的一个唯一的文件就成为当前要解决的问题,但这难不倒计算机科学家,因为从树型结构的角度来看,树中的每个结点都可以被一条从根开始,一直到达的结点的路径所描述,而这种描述方式就被称为文件的绝对路径(absolute path)。

C:\Program Files (x86)\Microsoft\Temp\EU5153.tmp

除了可以从根开始进行路径的描述,我们可以从任意结点出发,进行路径的描述,而这种描述方式就被称为相对路径(relative path),相对于当前所在结点的一条路径

.\表示当前目录
. .\表示上级目录

这里的分隔符可以是,也可以是/,但是为了避免\与字符组合i形成转义字符,需要用\来转义一下其中的一个,

其他知识

即使是普通文件,根据其保存数据的不同,也经常被分为不同的类型,我们一般简单的划分为文本文件和二进制文件,分别指代保存被字符集编码的文本和按照标准格式保存的非被字符集编码过的文件。Windows 操作系统上,会按照文件名中的后缀来确定文件类型以及该类型文件的默认打开程序。但这个习俗并不是通用的,在 OSX、Unix、Linux 等操作系统上,就没有这样的习惯,一般不对文件类型做如
此精确地分类。
文件由于被操作系统进行了管理,所以根据不同的用户,会赋予用户不同的对待该文件的权限,一般地可以认为有可读、可写、可执行权限
Windows 操作系统上,还有一类文件比较特殊,就是平时我们看到的快捷方式(shortcut),这种文件只是对真实文件的一种引用而已。其他操作系统上也有类似的概念,例如,软链接(soft link)等。
最后,很多操作系统为了实现接口的统一性,将所有的 I/O 设备都抽象成了文件的概念,使用这一理念最为知名的就是 Unix、Linux 操作系统 —— 万物皆文件
技巧:
将文件拖入记事本,能看懂就是文本文件,看不懂就是二进制文件

Java 中操作文件

在这里插入图片描述
站在CPU的角度,将数据从内存读到硬盘中,是输出,从硬盘读取到内存中,是输入
本节内容中,我们主要涉及文件的元信息、路径的操作,暂时不涉及关于文件中内容的读写操作。
Java 中通过 java.io.File 类来对一个文件(包括目录)进行抽象的描述。注意,有 File 对象,并不代表真实存在该文件

构造方法

在这里插入图片描述

方法

在这里插入图片描述

package Thread;import java.io.File;
import java.io.IOException;public class demo1 {public static void main(String[] args) throws IOException {File file = new File("d:/text.txt");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());}
}

在这里插入图片描述

package Thread;import java.io.File;
import java.io.IOException;public class demo1 {public static void main(String[] args) throws IOException {File file = new File("./text.txt");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());}
}

在这里插入图片描述
这里的getAbsolutePath会将工作路径与设定的当前路径相结合,工作路径就是程序所在的路径,getCanonicalPath则是会将getAbsolutePath合成的目录进行整理优化,去掉冗余的部分

创建文件

package Thread;import java.io.File;public class demo2 {public static void main(String[] args) {File file = new File("./text.txt");System.out.println(file.exists());System.out.println(file.isFile());System.out.println(file.isAbsolute());}
}

在这里插入图片描述
在这里插入图片描述

package Thread;import java.io.File;
import java.io.IOException;public class demo2 {public static void main(String[] args) throws IOException {File file = new File("./text.txt");file.createNewFile();System.out.println(file.exists());System.out.println(file.isFile());System.out.println(file.isAbsolute());}
}

在这里插入图片描述
在这里插入图片描述
可以看出,第一段代码,由于并没有创建一个text.txt的文件,所以打印都是false,而第二个代码,从目录中可以看到,已经将text.txt创建出来了,由于是newfile创建出来的,所以打印结果是true true false

删除文件

package Thread;import java.io.File;public class demo3 {public static void main(String[] args) throws InterruptedException {File file = new File("./text.txt");
//        file.delete();file.deleteOnExit();Thread.sleep(5000);}
}

在这里插入图片描述
上述代码,delate和deleteOnExit都可以将文件删除,不同的是,deleteOnExit是需要等到程序结束后才会将文件删除

创建目录

package Thread;import java.io.File;
import java.util.logging.FileHandler;public class demo4 {public static void main(String[] args) {File file = new File("./textDir");//mkdir一次只能创建一个目录,mkdirs一次可以创建很多个目录file.mkdir();
//        file.mkdirs();}
}

在这里插入图片描述

package Thread;import java.io.File;
import java.util.logging.FileHandler;public class demo4 {public static void main(String[] args) {File file = new File("./textDir/111/222/333");//mkdir一次只能创建一个目录,mkdirs一次可以创建很多个目录
//        file.mkdir();file.mkdirs();}
}

在这里插入图片描述

重命名

package Thread;import java.io.File;public class demo5 {public static void main(String[] args) {File file = new File("./test.txt");File file2 = new File("./test2.txt");file.renameTo(file2);}
}

我们先将file文件给创建出来,再利用rename将file文件名改为filename
在这里插入图片描述
在这里插入图片描述
rename还可以起到文件移动的作用

package Thread;import java.io.File;public class demo5 {public static void main(String[] args) {File file = new File("./test.txt");File file2 = new File("./src/test2.txt");file.renameTo(file2);}
}

在这里插入图片描述
此时文件test.txt已经从src目录外面给挪到src里面去了

文件内容的读写 —— 数据流

文件这里的内容本质是来自于硬盘,硬盘又是操作系统管理的,使用某个编程语言操作文件,本质上都是需要调用系统的api,
虽然不同的编程语言,操作文件的api有所差别,但是,基本步骤都是一样的,
文件内容的操作核心步骤,有四个
1.打开文件
2.读文件
3.写文件
4.关闭文件

javaIO流是一个比较庞大的体系,涉及到非常多的类,这些不同类,都有各自不同的特性,但是总的来说,使用方法都是类似的,
1.构造方法,打开文件
2.close方法,关闭文件,
3.如果衍生自InputStream或者Read,就可以使用read方法来读数据
4.如果衍生自OutputStreadm或者Writer,就可以使用writer方法来读数据
接下来,我们来举个例

Reader/Writer(字符流)

后续的一些操作字符的类都是衍生自这两个类,是操作字符为单位(文本文件)
先提前再d盘创建一个文件,写入一些数据后,我们尝试将利用程序其打开并读取

在这里插入图片描述
在这里插入图片描述

package Thread;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;//Read的使用
public class demo6 {public static void main(String[] args) throws IOException {Reader reader = new FileReader("D:/Data/test.txt");try {}finally {reader.close();}}
}

这里的close非常重要,是用来释放不必要的资源的,这是因为,让一个进程打开一个文件,是需要从系统中申请一定的资源的(占用进程的pcb里的文件描述符表中的资源,这里的表是一个顺序表,长度有限,不会自动扩容)
,如果不释放,就会出现"文件资源泄露"这个很严重的问题,一旦一直打开文件,而又不去关闭不用的文件,文件描述符表就会被占满,后续就无法继续打开新的文件了
上述的finally虽然也能够解决问题,但是不够优雅,我们可以使用try with resources

package Thread;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;//Read的使用
public class demo6 {public static void main(String[] args) throws IOException {try(Reader reader = new FileReader("D:/Data/test.txt")){//只要try代码块执行完了,就会自动调用到close//括号里面还可以创建多个对象,用;隔开}}
}

文件流中的任意对象,都可以按照上述的讨论来进行close

package File;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;public class demo1 {public static void main(String[] args) {try(Reader reader = new FileReader("d:/data/test.txt")) {
//            reader.read();//从文件中读取一个字节,返回类型是一个两个字节的Integerwhile (true){char []buf = new char[1024];int n = reader.read(buf);//通过read,就会把本来是一个空的数组,填充上内容,此处的参数就是一个输出型参数//这里的返回值是一个整型变量,表示实际读取到的字符个数,如果文件访问到末尾了,比如eof,就会返回一个-1if (n==-1){break;}for (int i =0;i<n;i++){System.out.print(buf[i]+" ");}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

在这里插入图片描述

在这里插入图片描述
还有这个方法,主要用在从多个文件中读取不同位置的数据.
写文件: 输出,使用方法和输入非常相似,关键操作是write,write之前要打开文件,用完了也需要关闭文件
输出流对象(无论是字节流还是字符流),都会在打开文件之后,清空文件内容
Write这个方法可以直接传输一个字符串,这是非常方便的

package File;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class demo4 {public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("d:/data/test.txt")){writer.write("hello java");}}
}

在这里插入图片描述
若想把新的内容加在之前的内容后面,就可以采用追加的方式,也就是在打开文件的时候,添加一个参数

package File;import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;public class demo4 {public static void main(String[] args) throws IOException {try(Writer writer = new FileWriter("d:/data/test.txt",true)){writer.write("hello java2");}}
}

在这里插入图片描述

InputStream/OutputStreadm(字节流)

后续的一些操作字节的类都是衍生自这两个类,是操作字节为单位(二进制文件)
InputStream是字节流,用法和Reader非常相似,文本文件也可以用字节流打开,只不过此时读到的每个字节,就不是完整的字符了

package File;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;public class demo2 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("d:/data/test.txt")){
//            inputStream.read();//一次读一个字节,虽然返回值是int,但是实际上只有0-255,也就是一个字节的大小while (true){byte []buf = new byte[1024];int n = inputStream.read(buf);//一次读若干字节,尝试填满数组if (n==-1){break;}for (int i =0;i<n;i++){System.out.printf(" %x ", buf[i]);}}}}
}

在这里插入图片描述

在这里插入图片描述
一次读取若干字节,填满一部分

scanner

public class demo3 {public static void main(String[] args) throws IOException {try(InputStream inputStream = new FileInputStream("d:/data/test.txt")){Scanner scanner = new Scanner(inputStream);String s = scanner.next();System.out.println(s);}}
}

在这里插入图片描述
以前学习的Scanner操作,在这里完全适用,但是,要注意,Scanner只是用来读取文本文件的,不适合读取二进制文件
OutputStream使用方式和Write完全一样,只是不能使用字符串参数,只能按照字节,或者字节数来写入
Scanner搭配inputStream 达到简化代码的效果,
PrintWriter搭配OutputStream,提供了一系列的方法,printf,println

例题

1.扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要

删除该文件

package File;import java.io.File;
import java.io.IOException;
import java.util.Scanner;//扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)
//        注意:我们现在的方案性能较差,所以尽量不要在太复杂的目录下或者大文件下实验
public class demo5 {public static Scanner scanner = new Scanner(System.in);public static void main(String[] args) throws IOException {System.out.println("请输入想要查找的根目录");File dir = new File(scanner.next());System.out.println("请输入想要查找的文件");File file = new File(scanner.next());if (!dir.isDirectory())return;ScanDir(dir,file);}public static void ScanDir(File dir , File file) throws IOException {File [] files = dir.listFiles();if (files.length==0||files==null)return;for (File file1:files) {System.out.println(file1.getCanonicalPath());if (file.isDirectory()){ScanDir(file1,file);} else {DealFile(file1,file);}}}public static void DealFile(File dir , File file){if (dir!=file)return;System.out.println("是否要删除该文件(Y/N)");String s = scanner.next();if (s=="Y"||s=="N")file.delete();}}

2.进行普通文件的复制

package File;import java.io.*;
import java.util.Scanner;//进行普通文件的复制
public class DEMO6 {public static void main(String[] args) throws IOException {Scanner scanner = new Scanner(System.in);System.out.println("请输入想要复制的文件");String file1 = scanner.next();File srcFile = new File(file1);if (!srcFile.isFile()){return;}System.out.println("请输入文件复制的目的地");String file2 = scanner.next();File destFile = new File(file2);if (!destFile.getParentFile().isDirectory())return;try(InputStream inputStream = new FileInputStream(srcFile);OutputStream outputStream = new FileOutputStream(destFile)){byte[]buf = new byte[1024];while (true){int n = inputStream.read(buf);if (n==-1)break;outputStream.write(buf,0,n);}}}
}

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

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

相关文章

Unity 2021.3发布WebGL设置以及nginx的配置

使用unity2021.3发布webgl 使用Unity制作好项目之后建议进行代码清理&#xff0c;这样会即将不用的命名空间去除&#xff0c;不然一会在发布的时候有些命名空间webgl会报错。 平台转换 将平台设置为webgl 设置色彩空间压缩方式 Compression Format 设置为DisabledDecompre…

模板注入 [WesternCTF2018]shrine1

打开题目 直接查看源代码 发现注册了一个名为FLAG的config&#xff0c;这里可能有flag&#xff0c; 存在flask-jinja2模板注入&#xff0c; 并且存在黑名单过滤 输入shrine/{{7*7}}验证成功 通过url_for()与globals()函数&#xff0c;绕过黑名单 /shrine/{{url_for.__globa…

基于stm32单片机智能矿井救援小车系统设计

作为一个矿产资源丰富的国家势必需要通过矿井来进行开采&#xff0c;而随着开采的深入在很多地质构造不同矿井中极易因为各种原因而造成事故&#xff0c;但由于危险的存在使得很多时候都无法第一时间派遣救援人员下到矿井施以救援。科学技术的进步和机器人技术的成熟彻底改变了…

零样本带解释性的医学大模型

带解释性的医学大模型 提出背景解法拆解方法的原因对比以前解法 零样本带解释性的医学大模型如何使用CLIP模型和ChatGPT来进行零样本医学图像分类用特定提示查询ChatGPT所生成的医学视觉特征描述相似性得分在不同症状上的可视化&#xff0c;用于解释模型的预测注意力图的可视化…

挑战杯 基于大数据的时间序列股价预测分析与可视化 - lstm

文章目录 1 前言2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &…

kafka为什么性能这么高?

Kafka系统架构 Kafka是一个分布式流处理平台&#xff0c;具有高性能和可伸缩性的特点。它使用了一些关键的设计原则和技术&#xff0c;以实现其高性能。 上图是Kafka的架构图&#xff0c;Producer生产消息&#xff0c;以Partition的维度&#xff0c;按照一定的路由策略&#x…

二手货wordpress企业网站主题模板

二手车wordpress主题模板 简洁的二手车wordpress主题模板&#xff0c;适合做二手车业务的公司官方网站使用。 https://www.jianzhanpress.com/?p3473 wordpress二手物资回收主题 绿色wordpress二手物资回收主题&#xff0c;用于二手物资回收公司WP建站使用。 https://www.…

07 MyBatis之高级映射 + 懒加载(延迟加载)+缓存

1. 高级映射 例如有两张表, 分别为班级表和学生表 自然, 一个班级对应多个学生 像这种数据 , 应该如果如何映射到Java的实体类上呢? 这就是高级映射解决的问题 以班级和学生为例子 , 因为一个班级对应多个学生 , 因此学生表中必定有一个班级编号字段cid 但我们在学生的实体…

MIT-BEVFusion系列九--CUDA-BEVFusion部署4 c++解析pytorch导出的tensor数据

目录 创建流打印 engine 信息打印结果内部流程 启动计时功能加载变换矩阵并更新数据&#xff08;重要&#xff09;内部实现 该系列文章与qwe一同创作&#xff0c;喜欢的话不妨点个赞。 在create_core方法结束后&#xff0c;我们的视角回到了main.cpp中。继续来看接下来的流程。…

【MySQL系列 04】深入浅出索引

一、索引介绍 提到数据库索引&#xff0c;相信大家都不陌生&#xff0c;在日常工作中会经常接触到。比如某一个 SQL 查询比较慢&#xff0c;分析完原因之后&#xff0c;你可能就会说“给某个字段加个索引吧”之类的解决方案。 但到底什么是索引&#xff0c;索引又是如何工作的…

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战【第95篇—自动化操作读写Excel 】

自动化操作读写Excel —— xlrd 和 xlwt 模块参数说明与代码实战 在日常工作中&#xff0c;Excel表格是不可或缺的数据处理工具。为了提高工作效率&#xff0c;Python中的xlrd和xlwt模块为我们提供了强大的功能&#xff0c;使得自动化操作Excel变得更加简便。本文将介绍xlrd和…

FastJson反序列化漏洞(Fastjson1.2.47)

一、FastJson Fastjson 是一个阿里巴巴公司开源的 Java 语言编写的高性能功能完善的 JSON 库。可以将Java 对象转换为 JSON 格式(序列化)&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象&#xff08;反序列化&#xff09; 它采用一种“假定有序快速匹配”的算法&…