详解文件IO操作 川长思鸟来 2023-09-26 09:02 17阅读 0赞 **目录** 1. 基础知识 文件操作 2. File类 3. 流(针对文件内容操作读写) 3.1 InputStream 概述 3.2 Scanner 4. 代码小练习 -------------------- ## 1. 基础知识 ## > **(1)狭义上的文件就是,存储在硬盘上的数据,这些以“文件”为单位,组织在一起** 常见的文件(文本文件、图片、视频、音频、可执行程序...) 文件夹也叫做“目录”,这也是一种特殊的文件 我们在电脑文件资源管理器中,随便打开一个,可以看到这些就是狭义上的文件 ![838dff94acce427097ffa0c1b1f2ffe3.png][] > **(2)广义上的文件就是,操作系统负责管理软硬件资源,操作系统(Linux)一般都会将这些资源都统一抽象为“文件”来进行管理。** 比如,电脑上的键盘,电脑想从键盘读取数据,就是把键盘抽象为一个文件,读这个文件就能读到用户输入的案件内容。 再比如,电脑上的音响,电脑想给音响发送数据播放音乐,就是把音响抽象为一个文件,写这个文件就可以让音响播放音乐 本篇所写的文件操作就是,指狭义上的文件 **(3)描述电脑上一个文件的具体位置,通过“路径”来描述,有两种** **a)绝对路径:** **D:\\腾讯软件\\QQ音乐\\QQMusic\\QQMusicUp.exe** ![4a78fd167a11434aba26bb55a7da23e5.png][] 目录之间的分割符,可以使用 \\ (反斜杠) ,也可以使用 / (斜杠) 但是我们在写代码时,最好使用 / (斜杠),来表示路径 **b)相对路径: 写相对路径,必须要知道基准路径是什么** ![e2951699e3244412b33ff1e12e512cba.png][] 需要注意,如果使用当前的基准路径找不到QQMusicUp.exe ![77bb5415784d4b2b92f09dd77baf4ef6.png][] 那就可以使用 ..返回到上级目录(..表示当前路径的上级路径) 当前是: D:\\腾讯软件\\腾讯会议\\WeMeet 第一次使用.. 返回到 D:\\腾讯软件\\腾讯会议 第二次使用.. 返回到 D:\\腾讯软件 这样就可以在 D:\\腾讯软件 中往下找了 -------------------- ## 文件操作 ## > 文件操作,是属于操作系统层面,提供的一些API > > 不同的操作系统,提供的API是不一样的 > > 而Java就在JVM中把不同系统的操作文件的API进行封装了,这样我们就可以使用Java中的库的代码来操作文件了 ## 2. File类 ## Java 中通过 java.io.File 类对一个文件(包括目录)进行操作 注意:有 File 对象,并不代表真实存在该文件。 注意下面的这操作,只是在操作“文件系统”(操作系统中管理文件的核心功能) 新增文件、删除文件、新增目录、列出目录内容。重命名、获取路径... 这些都不是针对文件内容的操作 **具体FIle的构造和方法,大家可以翻看一下JDK帮助手册,没有的可以私信我给你发一份** **demo1,看一下File的常用方法** public class demo01 { public static void main(String[] args) throws IOException { // File f = new File("D:/test.txt"); File f = new File("./test.txt"); System.out.println(f.getParent()); System.out.println(f.getName()); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } } **demo02, 判断文件是否存在,不存在就创建** public class demo02 { public static void main(String[] args) throws IOException { File f = new File("./test.txt"); //判定存在 System.out.println(f.exists()); //判定是否是目录 System.out.println(f.isDirectory()); //判定是否是文件 System.out.println(f.isFile()); //把这个文件创建出来 f.createNewFile(); //判定存在 System.out.println(f.exists()); //判定是否是目录 System.out.println(f.isDirectory()); //判定是否是文件 System.out.println(f.isFile()); } } ![6e735aa9d9eb42f7b1e00a3f44409b60.png][]![3d59f3507b964bd5b1046e69726c8b2a.png][] **demo03,删除文件** public class demo03 { public static void main(String[] args) { File f = new File("./test.txt"); f.delete(); } } ![b07cede5407e4d9d8e624b608f291200.png][]可以看到代码运行后,test.txt 删除成功 > 还有一个是,deleteOnExit 进程退出时删除文件 **demo04,创建目录** //创建目录 public class demo04 { public static void main(String[] args) { File f = new File("./testDir"); f.mkdir(); } } 运行代码后,可以看到目录创建成功![ae1984b9d69c47659f3b46cb4ac698f2.png][] > **注意 mkdir 是创建单层目录 mkdirs 是创建多层目录** public class demo04 { public static void main(String[] args) { File f1 = new File("./testDir/aaa/bbb"); f1.mkdirs(); } } ![5dfd53eeb11d48b4a58984dd95b6b89e.png][] **demo05,重命名** public class demo05 { //重命名 public static void main(String[] args) { File srcFile = new File("aaa.txt"); File destFile = new File("bbb.txt"); destFile.renameTo(destFile); } } 程序运行前,![f46f5f51c58543cbbe017cf99bbd56b8.png][]程序运行后,![ecbe88dd86c44d258c6fda7d3587e677.png][] **demo06,返回 File 对象代表的目录下的所有文件名** public class demo06 { public static void main(String[] args) { File f = new File("./testDir"); String[] results = f.list(); System.out.println(Arrays.toString(results)); } } ![6a3b831f28d94e84b65e22a3f9e327c4.png][] -------------------- ## 3. 流(针对文件内容操作读写) ## ### 3.1 **InputStream** **概述** ### > Java标准库,在“流”的概念上,提供了一组类,完成读写文件的操作 > > 这组类,分为两种( **这两种都是抽象类,不能实例化**) > > **a)字节流(以字节为基本单位),适用于二进制文件** > > **InputStream 读 OutputStream 写** > > **b)字符流(以字符为基本单位),适用于文本文件** > > **Reader 读 Writer 写** > > 上面的这些都是 父类, > > **在标准库中,给这些父类还提供了各种子类的实现,以适应各种不同常见下的读写需求** > > **InputStream --> FIleInputStream OutputStream --> FileOutputStream** > > **Reader --> FileReader Writer --> FileWriter** InputStream <table style="width:600px;"> <thead> <tr> <th>方法</th> <th>说明</th> </tr> </thead> <tbody> <tr> <th>int read()</th> <td>读取一个字节的数据,返回-1代表已经完全读完了</td> </tr> <tr> <th>int read(byte[] b)</th> <td>最多读取b.length字节的数据到b中,返回实际读到的数量;-1代表已经读完了</td> </tr> <tr> <th>int read(byte[] b, int off, int len)</th> <td>最多读取len - off 字节的数据到b中,放在从 off 开始,返回实际读到的数量;-1代表已经读完</td> </tr> <tr> <th>void close()</th> <td>关闭字节流</td> </tr> </tbody> </table> > int read(byte\[\] b) 和 int read(byte\[\] b, int off, int len) 是把读到的内容放到参数字节b数组中 > > 参数b用来存放方法读取到的结果 > > 需要注意正常情况下,对于方法来说,参数表示的是“输入信息”,返回值才是“输出信息” > > 但此时,是用参数b来作为存放输出结果的内容,b称为是“输出型参数” **(1)InputStream read()读取文件中的字节数据** ![a025b48c022442239f6e95a1140291a0.png][] public class demo07 { public static void main(String[] args) throws IOException { //打开文件 InputStream inputStream = new FileInputStream("./bbb.txt"); while(true) { int b = inputStream.read(); if(b == -1) { break; } System.out.println(b); } //关闭文件 inputStream.close(); } } **(2)OutputStream write()写文件** > **需要注意的是,使用OutputStream写文件时,只要打开文件成功,就会把文件原有内容清空,****重新给进写** ![86190c5e3f444fecbe50eb4da2ee1388.png][] public class demo08 { public static void main(String[] args) throws IOException { OutputStream outputStream = new FileOutputStream("./bbb.txt"); outputStream.write(97); outputStream.write(98); outputStream.write(99); outputStream.close(); } } **(3)Reader 使用字符流读文件** ![0d5cb99de1064192a098d943a0db0023.png][] **需要注意read读取到的是int类型,要用int类型来接收,最后打印时强转为char类型** //使用字符流读文件 public class demo09 { public static void main(String[] args) throws IOException { Reader reader = new FileReader("./bbb.txt"); while(true) { //把读到的内容用ret接收一下 int ret = reader.read(); //判断一下ret是不是-1如果是,那就是读完了 if(ret == -1) { break; } //如果没有读完就再强转接收打印出来 char ch = (char)ret; System.out.println(ch); } reader.close(); } } **(4)Writer 使用字符流来写文件** ![dec0a2900ead454590752551f7d71a51.png][] public class demo10 { public static void main(String[] args) throws IOException { //使用字符流来读文件 Writer writer = new FileWriter("./bbb.txt"); writer.write("hello world"); writer.close(); } } ![7895a040b2194289a84c6740f8576460.png][] ### 3.2 Scanner ### > **针对文本文件,使用字符流的时候,还可以使用Scanner来进行读取** > > **InputStream是字节流** > > **Scanner 是在InputStream的基础上,包装的字符流** public class demo11 { public static void main(String[] args) throws IOException { //使用scanner 读取文本文件 InputStream inputStream = new FileInputStream("./bbb.txt"); //可以给Scanner的构造对象中传入一个 字符流对象 Scanner scanner = new Scanner(inputStream); while(scanner.hasNext()) { System.out.println(scanner.next()); } inputStream.close(); } } ![2e2d8ca8d970449581208a01880d8628.png][] **使用PrintWriter可以简化写文件操作开发** public class demo12 { public static void main(String[] args) throws IOException { //针对写文件来说,还可以使用 PrintWriter 来简化开发 OutputStream outputStream = new FileOutputStream("./bbb.txt"); PrintWriter writer = new PrintWriter(outputStream); writer.println(); writer.printf("a = %d\n", 10); outputStream.close(); } } > **进行文件操作,一定要进行close(否则会造成文件资源泄露)** > > **如果在代码中,close 前面的代码抛出异常了,后面的 close 就执行不到了** **所以在写代码时,可以使用 try\_finally来保证 close一定会执行到** public static void main(String[] args) throws IOException { //针对写文件来说,还可以使用 PrintWriter 来简化开发 OutputStream outputStream = null; try{ OutputStream outputStream1 = new FileOutputStream("./bbb.txt") PrintWriter writer = new PrintWriter(outputStream); writer.println(); writer.printf("a = %d\n", 10); } finally { outputStream.close(); } } > **也可以直接将OutputStream写进try中(try with resources 也就是带资源的try)** > > **把要关闭的对象写到try的()中,当try结束,就会自动的调用到,对应对象的close方法** > > **而且支持一个()放多个对象,多个对象的创建之间使用 封号 “;”分割就可以了** public class demo12 { public static void main(String[] args) throws IOException { //针对写文件来说,还可以使用 PrintWriter 来简化开发 try(OutputStream outputStream = new FileOutputStream("./bbb.txt")){ PrintWriter writer = new PrintWriter(outputStream); writer.println(); writer.printf("a = %d\n", 10); } } } ## 4. 代码小练习 ## **(1) 扫描指定目录,并找到名称中包含指定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件** a)先让用户输入:要扫描的路径+要查找的词 b)遍历目录,找到名字匹配的文件 这个需要用到一个核心方法:**listFiles() 如果当前是一个目录,直接调用这个方法,就能把当前目录中包含的文件和子目录都能够列举出来** 但是这个方法只能列举出一层,没法直接列出子目录中的子目录 解决的方法就是,遍历listFIles的结果,针对每一个元素,进行判定,看是一个普通文件,还是一个目录。(此处的目录结构本质上是一个“树”) 如果是普通文件,直接判定文件名包含了要查找的词,如果是目录,递归的调用listFiles c)询问用户是否删除 import java.io.*; import java.util.Scanner; public class demo01 { public static void main(String[] args) throws IOException { //1.让用户输入 要扫描的路径+要查找的关键词 Scanner scanner = new Scanner(System.in); System.out.println("请输入要扫描的路径:"); File rootDir = new File(scanner.next()); //用isDirectory判断一下rootDir是不是目录 if(!rootDir.isDirectory()) { System.out.println("您输入的目录不存在!"); return; } System.out.println("请输入要搜索的关键词:"); String toDelete = scanner.next(); //2.遍历目录,找到名字匹配的文件 scanDir(rootDir, toDelete); } //借助这个方法进行递归遍历 private static void scanDir(File rootDir, String toDelete) throws IOException { System.out.println("当前访问:" + rootDir.getCanonicalPath()); File[] files = rootDir.listFiles(); if(files == null) { //说明 rootDir是一个空的目录 return; } //如果目录非空,则循环遍历每个元素 for (File f : files) { if(f.isDirectory()) { scanDir(f, toDelete); }else { //不是目录,是普通文件,判断文件名是否是所要查找的,是否要进行删除 checkDelete(f, toDelete); } } } private static void checkDelete(File f, String toDelete) throws IOException { //看一下这个 文件 中是否包含了 toDelete if(f.getName().contains(toDelete)) { System.out.println("这个关键词" + toDelete + "被" + f.getCanonicalPath() + "包含了,是否要进行删除?(Y/N)"); Scanner scanner = new Scanner(System.in); String choice = scanner.next(); if(choice.equals("Y") || choice.equals("y")) { f.delete(); System.out.println("删除成功!"); } } } } ![3f6fa4e0b84e44baa3f23399a7031ba4.png][] **(2)进行普通文件的复制** 把第一个文件打开,把里面的内容逐个字节的读出来,写入到第二个文本中就可以了 使用字节流来进行操作,字节流也是可以用来拷贝文件的 import java.io.*; import java.util.Scanner; //进行普通文件的复制 public class demo02 { public static void main(String[] args) { //1.先输入要复制哪个文件 和 将文件复制到哪里去(目标文件) Scanner scanner = new Scanner(System.in); System.out.println("请输入源文件:"); //使用File的作用是可以判断文件是否存在 File srcFile = new File(scanner.next()); System.out.println("请输入目标文件:"); File destFile = new File(scanner.next()); if(srcFile.isFile()) { System.out.println("输入的源文件有误!"); return; } //getParentFile()如果文件不存在就抛出异常 if(!destFile.getParentFile().isDirectory()) { System.out.println("输入的目标文件有误!"); return; } //2.打开源文件,按照字节读取内容,依次写入到目标文件中 try(InputStream inputStream = new FileInputStream(srcFile); OutputStream outputStream = new FileOutputStream(destFile)) { //读 src 的每个字节,写入到 dest中 while (true) { int ret = inputStream.read(); //如果读到-1就结束 if(ret == -1) { break; } outputStream.write(ret); } } catch (IOException e) { e.printStackTrace(); } } } **(3)扫描指定目录,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)** import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; public class demo03 { public static void main(String[] args) throws IOException { //1.输入路径和要查询的关键词 Scanner scanner = new Scanner(System.in); System.out.println("请输入要扫描的路径:"); File rootDir = new File(scanner.next()); System.out.println("请输入要查询的关键词:"); String toFind = scanner.next(); //2.递归的进行扫描目录 scanDir(rootDir, toFind); } private static void scanDir(File rootDir, String toFind) throws IOException { //listFiles将当前目录中的文件和子目录都列举出来 File[] files = rootDir.listFiles(); if(files == null) { return; } for (File f : files) { if(f.isDirectory()) { scanDir(f, toFind); } else { checkFile(f, toFind); } } } private static void checkFile(File f, String toFind) throws IOException { //1.先检查文件名 if(f.getName().contains(toFind)) { System.out.println(f.getCanonicalPath() + " 文件名中包含 " + toFind); } //2.检查文件内容 try(InputStream inputStream = new FileInputStream(f)) { StringBuilder stringBuilder = new StringBuilder(); Scanner scanner = new Scanner(inputStream); //这里需要按行读取了 while (scanner.hasNextLine()) { stringBuilder.append(scanner.nextLine() + "\n"); } if(stringBuilder.indexOf(toFind) > -1) { System.out.println(f.getCanonicalPath() + " 文件内容包含 " + toFind); } } } } ![a2f572cd71f949f8be3dcc8c99025cf8.png][] [838dff94acce427097ffa0c1b1f2ffe3.png]: https://img-blog.csdnimg.cn/838dff94acce427097ffa0c1b1f2ffe3.png [4a78fd167a11434aba26bb55a7da23e5.png]: https://img-blog.csdnimg.cn/4a78fd167a11434aba26bb55a7da23e5.png [e2951699e3244412b33ff1e12e512cba.png]: https://img-blog.csdnimg.cn/e2951699e3244412b33ff1e12e512cba.png [77bb5415784d4b2b92f09dd77baf4ef6.png]: https://img-blog.csdnimg.cn/77bb5415784d4b2b92f09dd77baf4ef6.png [6e735aa9d9eb42f7b1e00a3f44409b60.png]: https://img-blog.csdnimg.cn/6e735aa9d9eb42f7b1e00a3f44409b60.png [3d59f3507b964bd5b1046e69726c8b2a.png]: https://img-blog.csdnimg.cn/3d59f3507b964bd5b1046e69726c8b2a.png [b07cede5407e4d9d8e624b608f291200.png]: https://img-blog.csdnimg.cn/b07cede5407e4d9d8e624b608f291200.png [ae1984b9d69c47659f3b46cb4ac698f2.png]: https://img-blog.csdnimg.cn/ae1984b9d69c47659f3b46cb4ac698f2.png [5dfd53eeb11d48b4a58984dd95b6b89e.png]: https://img-blog.csdnimg.cn/5dfd53eeb11d48b4a58984dd95b6b89e.png [f46f5f51c58543cbbe017cf99bbd56b8.png]: https://img-blog.csdnimg.cn/f46f5f51c58543cbbe017cf99bbd56b8.png [ecbe88dd86c44d258c6fda7d3587e677.png]: https://img-blog.csdnimg.cn/ecbe88dd86c44d258c6fda7d3587e677.png [6a3b831f28d94e84b65e22a3f9e327c4.png]: https://img-blog.csdnimg.cn/6a3b831f28d94e84b65e22a3f9e327c4.png [a025b48c022442239f6e95a1140291a0.png]: https://img-blog.csdnimg.cn/a025b48c022442239f6e95a1140291a0.png [86190c5e3f444fecbe50eb4da2ee1388.png]: https://img-blog.csdnimg.cn/86190c5e3f444fecbe50eb4da2ee1388.png [0d5cb99de1064192a098d943a0db0023.png]: https://img-blog.csdnimg.cn/0d5cb99de1064192a098d943a0db0023.png [dec0a2900ead454590752551f7d71a51.png]: https://img-blog.csdnimg.cn/dec0a2900ead454590752551f7d71a51.png [7895a040b2194289a84c6740f8576460.png]: https://img-blog.csdnimg.cn/7895a040b2194289a84c6740f8576460.png [2e2d8ca8d970449581208a01880d8628.png]: https://img-blog.csdnimg.cn/2e2d8ca8d970449581208a01880d8628.png [3f6fa4e0b84e44baa3f23399a7031ba4.png]: https://img-blog.csdnimg.cn/3f6fa4e0b84e44baa3f23399a7031ba4.png [a2f572cd71f949f8be3dcc8c99025cf8.png]: https://img-blog.csdnimg.cn/a2f572cd71f949f8be3dcc8c99025cf8.png
相关 Java文件IO操作:读写文件步骤详解 在Java中,进行文件I/O(Input/Output)操作主要包括以下几个步骤: 1. **创建File对象**: Java的`java.io.File`类用于表示文 心已赠人/ 2024年09月10日 08:30/ 0 赞/ 21 阅读
相关 文件操作和IO详解 ![v2-5119579f3b3a75da8d540ed2cebaa8f7\_bfly0213][v2-5119579f3b3a75da8d540ed2cebaa8f7_bfl 蔚落/ 2024年02月21日 07:06/ 0 赞/ 14 阅读
相关 IOS文件操作 1.从cache文件夹拷贝到document文件夹 NSString sqlFile = @"test.zip"; NSArray cachePath 快来打我*/ 2023年10月18日 11:23/ 0 赞/ 13 阅读
相关 详解文件IO操作 目录 1. 基础知识 文件操作 2. File类 3. 流(针对文件内容操作读写) 3.1 InputStream 概述 3.2 Scanner 4. 代码小练习 川长思鸟来/ 2023年09月26日 09:02/ 0 赞/ 18 阅读
相关 io 文件操作java_Java I/O技术之文件操作详解 在java程序设计中,I/O操作是通过java.io包中的类和接口来实现的,因此,我们第一步要做的就是import这个包。 java.io提供了一个File类,这是类很容易让 àì夳堔傛蜴生んèń/ 2022年11月03日 10:37/ 0 赞/ 118 阅读
相关 iOS 简单文件操作 import <Foundation/Foundation.h> int main(int argc, const char argv[]) { 小灰灰/ 2022年09月24日 01:25/ 0 赞/ 163 阅读
相关 文件IO操作 File类: file类是IO包中唯一代表磁盘文件本身的对象。file类定义了一些与平台无关的方法来操作文件,通过调用file类提供的各种文件。 能够完成创建,删除,重 你的名字/ 2022年06月08日 08:18/ 0 赞/ 210 阅读
相关 详解 Python文件与IO操作 1 文件输入/输出 数据持久化最简单的类型是普通文件,有时也叫平面文件(flat file)。它仅仅是在一个文件名下的字节流, 把数据从一个文件读入内存,然后从内存写入文... 朱雀/ 2020年09月05日 16:25/ 0 赞/ 957 阅读
还没有评论,来说两句吧...