Java文件IO相关类的使用与案例

举报
未见花闻 发表于 2022/07/31 21:40:12 2022/07/31
【摘要】 本篇文章将介绍文件IO,文件IO即文件输入(Input)与输出(Output),文件输入就是将文件中的内容读入内存中,文件输出就是将程序输出的内容写入到文件中,说了文件的输入与输入的概念,那你知道什么是文件吗?

⭐️前面的话⭐️

本篇文章将介绍文件IO,文件IO即文件输入(Input)与输出(Output),文件输入就是将文件中的内容读入内存中,文件输出就是将程序输出的内容写入到文件中,说了文件的输入与输入的概念,那你知道什么是文件吗?

📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创!
📆华为云首发时间:🌴2022年7月31日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《java核心技术》,📚《java编程思想》
💬参考在线编程网站:🌐牛客网🌐力扣
博主的码云gitee,平常博主写的程序代码都在里面。
博主的github,平常博主写的程序代码都在里面。
🍭作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!

🍎1.文件

🍏1.1文件的概念

平时我们所说的文件一般是储存在硬盘上的文件,比如.jpg.txt.mp3.mp4.pptx等文件,这些格式的文件都是储存在硬盘上的文件。
文件

而对于计算机中的文件的概念,它是一个广义的名词,除了上面我们所说的普通文件,它还包括目录,其实就是文件夹了,它也是文件的一种,目录也被称为目录文件。

在操作系统中,还会使用文件来描述其他的一些硬件和软件资源,比如网卡,操作系统将网卡也抽象成了一种“文件”,以简化程序的开发,除了网卡,还有我们所使用的键盘和显示屏也被操作系统抽象为文件。

🍏1.2文件的分类

文件主要分为两类,一类是文本文件,另一类是二进制文件,文本文件你使用记事本打开里面显示的是文本,二进制文件你使用记事本打开里面大概率会乱码。

计算机中保存和管理文件是通过操作系统中的文件系统这样的模块来负责的,文件系统一般通过树形结构来实组织磁盘中的普通文件和目录文件,但是不限于我们所熟悉的二叉树,往往是使用多叉树来实现的。

🍏1.3文件的路径

文件的路径包括两种,一种是绝对路径,以盘符开头,例如:D:\未见花闻\资料\课件,还有有一种是相对路径,以...开头开头的路径,相对路径必须有一个基准目录。
C:\Program Files\Java\jdk1.8.0_301\bin目录为例,以该路径为基准目录,假设我们要在bin文件夹中找到javac.exe文件,则使用相对路径表示为.\javac.exe,这里的.就表示基准目录路径C:\Program Files\Java\jdk1.8.0_301\bin路径。
javac
再次以C:\Program Files\Java\jdk1.8.0_301\bin目录为基准目录,我们要表示与bin文件夹在同一目录中的src.zip文件,我们可以使用..表示基准目录的父路径C:\Program Files\Java\jdk1.8.0_301,该文件的相对路径为..\src.zip

src
Java中提供了一个标准类将文件的路径抽象化了,即File类,下文会有File类的使用教程。

🍎2.Java文件IO

🍏2.1文件系统相关操作

🍊2.1.1简介

对于文件系统的操作就是对文件进行一些操作,主要的操作有下面这一些:

  1. 列出目录中有哪些文件。
  2. 创建文件。
  3. 创建目录。
  4. 删除文件。
  5. 文件重命名。
  6. 等等文件资源管理器中的一些功能。

java中提供了一个File类,能够完成对某一路径上的文件进行操作。

老规矩,先来认识一下File类和一些常用的一些方法,File类位于import java.io包,该类相当于一个抽象的文件路径,能够在指定的路径中进行文件的创建删除修改文件属性等,但是不能对文件的内容进行操作。

🍇 File类的属性(该类实例对象就是表示一个文件路径):

类型 成员
static String pathSeparator 与系统相关的路径分隔符字符,为方便起见,表示为字符串。
static char pathSeparatorChar 与系统相关的路径分隔符。
static String separator 与系统相关的默认名称 - 分隔符字符,以方便的方式表示为字符串。
static char separatorChar 与系统相关的默认名称分隔符。

🍇 File类构造方法,一共有四个,最常用的是传一个路径字符串,以对该路径的文件进行操作。

序号 方法 作用
1 public File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的文件实例。如果给定的字符串是空字符串,那么结果就是空的抽象路径名。
2 public File(String parent, String child) 从父路径名字符串和子路径名字符串创建新的文件实例。如果parent为null,则新的文件实例将通过调用给定子路径名字符串上的单参数文件构造函数来创建。
3 public File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的文件实例。如果parent为null,则新的文件实例将通过调用给定子路径名字符串上的单参数文件构造函数来创建。
4 public File(URI uri) 通过将给定的URI转换为抽象路径名来创建新的文件实例。

对于File类,目前以构造方法1创建实例对象为主,其他的一些构造方法看不懂也没关系,后面的演示都是以构造方法1来创建对象。

构造方法1就是根据你所给的路径来创建一个文件实例对象,这个路径可以是绝对路径,也可以是相对路径,如果通过绝对路径创建文件实例对象,那么就是在所给的绝对路径目录上进行相关文件的路径,但是如果你给了相对路径,在不同的环境下,基准目录不相同,比如如果在命令行运行,则会以在命令行运行程序的目录作为基准目录,如果在IDEA中运行,那基准目录就是你所建项目的目录,就是iml文件所在的目录。

idea

🍊2.1.1File类中的常用获取方法

File类获取操作常用方法:

序号 返回值 方法 作用
1 File getAbsoluteFile() 返回此File对象绝对形式路径的File对象引用。
2 String getAbsolutePath() 返回此File对象的绝对路径名字符串。
3 File getCanonicalFile() 返回此File对象的规范File对象引用。
4 String getCanonicalPath() 返回此File对象的规范绝对路径名字符串。
5 String getName() 返回由此抽象路径名表示的文件或目录的名称。
6 String getParent() 返回此File对象的父目录路径字符串,如果此父目录不存在,则返回null。
7 File getParentFile() 返回此File对象的父目录绝对路径形式的父File对象 ,不存在则返回null。
8 String getPath() 获取File对象的路径名字符串 。

简单演示一下,其实很简单,就是使用一个路径来构造File实例对象,然后这个对象就能对这个路径下的文件进行操作,就比如上面的一组方法都是获取的方法,能够得到File实例对象的一些基本信息,比如路径。

import java.io.File;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        //由于历史原因,Windows最开始用的是\作为分隔符,但是后面后悔了,不好改,所以Windows后来/\作为分隔符都可以,但系统默认的是\
        //使用\作为分隔符需要转义
        //File file = new File("D:\\未见花闻\\项目\\文件IOFile类演示.txt");
        //通过绝对路径字符串创建文件对象,创建文件对象时不会自动创建文件
        File file = new File("D:/未见花闻/项目/文件IOFile类演示/测试.txt");
        //获取当前文件对象的文件名
        System.out.println(file.getName());
        //获取当前文件的绝对路径字符串
        System.out.println(file.getAbsolutePath());
        //获取当前文件的规范化的绝对路径字符串
        System.out.println(file.getCanonicalPath());
        //获取当前文件父目录的路径字符串
        System.out.println(file.getParent());
        //获取当前文件对象构造时所传入的路径字符串
        System.out.println(file.getPath());

        System.out.println("================");

        //通过相对路径字符串创建文件对象
        File file2 = new File("./测试.txt");
        //获取当前文件对象的文件名
        System.out.println(file2.getName());
        //获取当前文件的绝对路径字符串
        System.out.println(file2.getAbsolutePath());
        //获取当前文件的规范化的绝对路径字符串
        System.out.println(file2.getCanonicalPath());
        //获取当前文件父目录的路径字符串
        System.out.println(file2.getParent());
        //获取当前文件对象构造时所传入的路径字符串
        System.out.println(file2.getPath());


        System.out.println("================");
		//获取file2绝对路径形式的File对象引用
        File file3 = file2.getAbsoluteFile();
        //获取当前文件对象的文件名
        System.out.println(file3.getName());
        //获取当前文件的绝对路径字符串
        System.out.println(file3.getAbsolutePath());
        //获取当前文件的规范化的绝对路径字符串
        System.out.println(file3.getCanonicalPath());
        //获取当前文件父目录的路径字符串
        System.out.println(file3.getParent());
        //获取当前文件对象构造时所传入的路径字符串
        System.out.println(file3.getPath());
    }
}

🍇 运行结果:
结果1

🍊2.1.3File类中的常用判断方法

🍇 File类判断操作常用方法:

序号 返回值 方法 作用
1 boolean canExecute() 测试应用程序是否可以执行此File对象表示的文件。
2 boolean canRead() 测试应用程序是否可以读取由此File对象表示的文件。
3 boolean canWrite() 测试应用程序是否可以修改由此File对象表示的文件。
4 boolean exists() 测试此File对象表示的文件或目录是否存在。
5 boolean isAbsolute() 测试这个File对象路径名是否是绝对路径。
6 boolean isDirectory() 测试此File对象路径表示的文件是否为目录。
7 boolean isFile() 测试此File对象表示的文件是否为普通文件。
8 boolean isHidden() 测试此File对象表示的文件是否为隐藏文件。

比如就演示项目所在文件夹为了,iml文件所在目录存在一个文件测试.txt,我们使用File来判断该文件的一些相关属性。
当前目录

import java.io.File;

public class TestDemo1 {
    public static void main(String[] args) {
        File file = new File("./测试.txt");

        //判断文件是否存在
        System.out.println(file.exists());
        //判断File对象的路径是否是绝对路径
        System.out.println(file.isAbsolute());
        //判断文件是否是文件夹(目录)
        System.out.println(file.isFile());
        //判断文件是否是隐藏文件
        System.out.println(file.isHidden());
        //判断文件是否能够执行/读/写
        System.out.println(file.canExecute());
        System.out.println(file.canRead());
        System.out.println(file.canWrite());
    }
}

🍇 运行结果:
结果2

🍊2.1.4文件的创建与删除

序号 返回值 方法 作用
1 boolean createNewFile() 当且仅当具有该名称的文件尚不存在时,原地创建一个新的空文件。
2 static File createTempFile(String prefix, String suffix) 在默认临时文件目录中创建一个空文件,使用给定的前缀和后缀生成其名称。
3 static File createTempFile(String prefix, String suffix, File directory) 在指定的目录中创建一个新的空文件,使用给定的前缀和后缀字符串生成其名称。
4 boolean delete() 删除由此File对象表示的文件或目录。
5 void deleteOnExit() 请求在虚拟机终止时删除由此File对象表示的文件或目录。
6 boolean mkdir() 在File对象表示的路径下创建目录。
7 boolean mkdirs() 在File对象表示的路径下创建多个目录,包括任何必需但不存在的目录。

🍇 常见方法演示:
还是以idea项目目录下进行演示操作,文件创建前,目录中只有之前保留的测试.txt和项目配置文件。
文件创建前

import java.io.File;
import java.io.IOException;

public class TestDemo2 {
    public static void main(String[] args) throws IOException {
        File file = new File("./creatFile.txt");
        //文件未创建的情况下创建新文件
        if (!file.exists()) {
            file.createNewFile();
            System.out.println("创建文件成功!");
        }
        //创建一个目录(文件夹)
        file = new File("./creat");
        file.mkdir();
        System.out.println("创建文件夹成功");
        //创建多个目录
        file = new File("./creat1/creat2/creat3");
        file.mkdirs();
        System.out.println("创建多个文件夹成功!");
    }
}

🍇 运行结果与目录下文件创建结果:
结果3
创建后
🍇 删除操作:

import java.io.File;

public class TestDemo3 {
    public static void main(String[] args) {
        //删除操作
        File file = new File("./测试.txt");
        file.delete();
    }
}

运行后,目录下测试.txt就被删除了,很简单就不多说了。

🍊2.1.5其他的常用方法

序号 返回值 方法 作用
1 String[] list() 记录File对象所表示的文件所在的目录下所有的文件名,以字符串数组形式返回
2 String[] list(FilenameFilter filter) 返回一个字符串数组,记录File对象所表示的文件所在的目录下满足文件过滤器筛选的文件名
3 File[] listFiles() 相比于方法1,返回的是文件数组
4 File[] listFiles(FileFilter filter) 相比于方法2,返回的是文件数组
5 File[] listFiles(FilenameFilter filter) 与方法4作用相同
6 boolean renameTo(File dest) 重命名文件,本质上是剪切粘贴操作

🍇 常用方法演示:

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class TestDemo4 {
    public static void main(String[] args) throws IOException {
        File file = new File("./");
        //获取当前路径目录下所有文件名
        System.out.println(Arrays.toString(file.list()));

        File f = new File("./aaa/bbb/ccc/ddd");
        File f2 = new File("./aaa");
        File tmp = new File("./zzz");
        //按照f对象创建目录
        f.mkdirs();
        //获取当前路径目录下所有文件名
        System.out.println(Arrays.toString(file.list()));
        //重命名aaa,或者说将aaa目录中的文件剪切至zzz
        System.out.println(f2.renameTo(tmp));
        //获取当前路径目录下所有文件名
        System.out.println(Arrays.toString(file.list()));
        System.out.println(f2.getName());//获取对象的文件名不变,但是文件没有了,因为将aaa目录剪切粘贴到zzz了
        System.out.println(tmp.getName());
    }
}

🍇 运行结果:

结果4

🍏2.2文件内容的读写

🍊2.2.1文件读写流

针对文件内容的读写,java提供了两组类和接口,分别用来针对两类文件的内容进行读写,一组是字节流对象,针对二进制文件的读写,另外一组是数据流对象,针对文本文件的读写
对于二进制文件内容的读写可以使用InputStream(读)和OutputStream(写)来操作,对于文本文件内容的读写可以使用Reader(读)和Writer(写)来操作,这四个java提供的标准类都是抽象类,我们在使用时常常使用它们的子类来创建对象,前后对应分别是FileInputStream, FileOutputStream, FileReader和FileWriter类,这几个类的使用和核心方法都是相同的,因此我们重点选择一组来介绍。

说到这,这些类为什么叫流对象?因为使用这些类对文件进行读写操作时,可以一次读一个字节(字符),也可以一次读多个字节(字符),就像水流一样,所以将这些对象叫做流对象,对文件进行写操作称为输出流,对文件进行读操作称为输入流。
流

🍊2.2.2文件内容的读写

因为Java提供的两组文件内容操作类的用法基本上一模一样,我就不一一把每个类的常用方法都列出来了,我选择一些通用的核心方法来介绍如何对文件的内容进行操作。

🍇 文件读操作的核心方法:

序号 方法 作用
1 public int read() throws IOException 单次单字节读取文件,返回值就是读取到的字节
2 public int read(byte b[]) throws IOException 单次多字节读取文件,将读取到的内容放在传入的数组中,返回值是读取文件的字节数
3 public int read(byte b[], int off, int len) throws IOException 单次多字节读取文件,返回值为读取的字节数,相较与方法2,读取到的内容会从数组指定下标off处开始放置,每次最多放入的长度为len
4 public int read() throws IOException 单次单字符读取文件,返回值就是读取到的字符
5 public int read(char cbuf[]) throws IOException 单次多字符读取文件,将读取到的内容放在传入的数组中,返回值是读取文件的字符数
6 abstract public int read(char cbuf[], int off, int len) throws IOException 单次多字符读取文件,返回值为读取的字符数,相较与方法5,读取到的内容会从数组指定下标off处开始放置,每次最多放入的长度为len
7 public void close() throws IOException 关闭文件

对于上面的读文件内容操作方法,前方法1-3是字节流对象的读操作,方法4-6是字符流对象的读操作,方法7通用。有一个小小的问题:字节流对象中写操作无参方法的返回值为什么是int,难道不应该是byte吗?
我们可以这样理解,因为返回值返回的是读取到的byte类型的值,我们知道如果文件读完了,该方法会返回-1,如果使用byte类型的返回值会出现一个问题,那就是返回值为-1就区分不了文件是读完了还是读到的字节值就是-1,所以就需要一个更大范围的返回值类型来进行返回,可以选择short/int,但字符流也是有这样的问题,于是就统一将返回值类型都定为int

🍇 文件写操作的核心方法:

序号 方法 作用
1 public void write(int b) throws IOException 单字节写入
2 public void write(byte b[]) throws IOException 将数组中的数据写入文件
3 public void write(byte b[], int off, int len) throws IOException 从数组指定起始位置开始将最大长度为len的内容写入文件
4 public void write(int c) throws IOException 单字符写入
5 public void write(char cbuf[]) throws IOException 字符流对象写操作的方法
6 abstract public void write(char cbuf[], int off, int len) throws IOException 字符流对象写方法
7 public void write(String str) throws IOException 将字符串写入文件
8 public void write(String str, int off, int len) throws IOException 将字符串指定位置写入文件
9 public void flush() throws IOException 刷新缓冲区

同理,方法1-3是字节流对象写操作的方法,方法4-8是字符流对象写操作方法。

对于字节流对象和字符流对象的创建,可以指定路径字符串构造,也可以使用File对象进行构造。
假设有一个文件中含有测试.txt的文本文件,该文件存有3个字母abc,使用一个数组接收数据,如果使用字节流对象读取,得到的结果是它们的ASCII码值,使用字符流对象读取,得到的就是abc三个字母,当然如果使用无参方法获取得到的都是编码值,因为两种流无参读方法都是int
读取文件

import java.io.*;

public class TestDemo5 {
    public static void main(String[] args) {
        try {
            //按照字节为单位读取
            InputStream inputStream = new FileInputStream("D:/未见花闻/项目/文件IOFile类演示/测试.txt");
            //按照以字符为单位读取
            Reader reader = new FileReader("D:/未见花闻/项目/文件IOFile类演示/测试.txt");

            while (true) {
                byte[] bytes = new byte[1024];
                int len = inputStream.read(bytes);
                if (len == -1) break;
                //字节
                for (int i = 0; i < len; i++) {
                    System.out.print(bytes[i] + "  ");
                }
            }
            //关闭文件
            inputStream.close();
            System.out.println();
            while (true) {
                char[] chars = new char[1024];
                int len = reader.read(chars);
                if (len == -1) break;
                //字符
                for (int i = 0; i < len; i++) {
                    System.out.print(chars[i] + "  ");
                }
            }
            //关闭文件
            reader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🍇 运行结果:

97  98  99  
a  b  c  
Process finished with exit code 0

文件读取完之后,要记得关闭文件(上面的写法有个问题就是如果读取时发生异常就无法及时关闭文件了,可以使用finally,不过要把读写对象定义在try语句外面)。使用下面的写法读取完会自动关闭文件,就不用担心忘记关闭文件了,更推荐下面的这种写法。

import java.io.*;

public class TestDemo6 {
    public static void main(String[] args) {
        try (InputStream inputStream = new FileInputStream("D:/未见花闻/项目/文件IOFile类演示/测试.txt")) {
            while (true) {
                byte[] bytes = new byte[1024];
                int len = inputStream.read(bytes);
                if (len == -1) break;
                //字节
                for (int i = 0; i < len; i++) {
                    System.out.print(bytes[i] + "  ");
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();
        try (Reader reader = new FileReader("D:/未见花闻/项目/文件IOFile类演示/测试.txt");) {
            while (true) {
                char[] chars = new char[1024];
                int len = reader.read(chars);
                if (len == -1) break;
                //字符
                for (int i = 0; i < len; i++) {
                    System.out.print(chars[i] + "  ");
                }
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🍇 运行结果:

97  98  99  
a  b  c  
Process finished with exit code 0

写操作也是类似的,为了演示方便,采用字符流对象进行演示,如果路径下的文件是不是普通文件就会报错,如果没有对应路径的普通文件,就会自动创建并写入数据,如果普通文件里面有内容就会先清空内容再写入。

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class TestDemo7 {
    public static void main(String[] args) {
        try (Writer writer = new FileWriter("D:\\未见花闻\\项目\\文件IOFile类演示\\creat.txt")) {
            writer.write("未见花闻");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

🍇 运行结果:
写操作

🍊2.2.3扫描指定文件并根据文件名删除指定普通文件

我们知道文件的组织结构是树形结构,所以扫描的时候可以通过树的遍历来实现,我们知道二叉树的遍历方式一共有4种,分别为前序遍历,中序遍历,后序遍历和层序遍历,前三种都是基于递归实现的,最后一种是基于队列实现的,只不过这里的扫描文件是多叉树遍历。其实逻辑都是一样的,现在我们来基于多叉树的前序遍历来进行文件的扫描。

import java.io.File;
import java.io.IOException;
import java.util.Scanner;

public class Program1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //1. 获取信息
        System.out.println("请输入需要扫描的文件夹:");
        String scanPath = sc.nextLine();
        System.out.println("请输入需要删除的文件名:");
        String fileName = sc.nextLine();

        File file = new File(scanPath);
        if (!file.isDirectory()) {
            System.out.println("输入的文件路径有误!");
            return;
        }
        //2. 遍历目录
        scanDire(file, fileName);
    }
    private static void scanDire(File rootDire, String fileName) {
        //1.获取当前文件夹下面的的文件
        File[] files = rootDire.listFiles();
        if (files == null) {
            //空目录,直接返回
            return;
        }
        //2.遍历当前文件夹所有文件,如果是普通文件就询问删除,否则继续遍历子文件夹
        for (File x : files) {
            if (x.isFile()) {
                if (x.getName().contains(fileName)) {
                    //删除文件
                    deleteFile(x);
                }
            } else if (x.isDirectory()){
                //继续遍历
                scanDire(x, fileName);
            }
        }
    }
    private static void deleteFile(File file) {
        Scanner sc = new Scanner(System.in);
        try {
            System.out.println("请确认是否需要删除文件(yes/no):" + file.getCanonicalPath());
        } catch (IOException e) {
            e.printStackTrace();
        }
        String str = sc.nextLine();
        if (str.equalsIgnoreCase("yes")) {
            boolean ret =file.delete();
            if (ret) System.out.println("已经成功删除!");
            else System.out.println("删除失败!");
        } else {
            System.out.println("已经取消删除!");
        }
    }
}

现在我们要通过上述程序把删除文件夹中请把我删除文件删除,具体文件如图:
扫描删除
🍇 运行后文件夹的结果:
删除结果

🍊2.2.4获取含有指定字符串的普通文件

给定你一个文件夹和一个字符串,找到该文件夹内所有含有该字符串内容的普通文件。
其实这个和上一个案例差不多,都需要对文件进行扫描,找到普通文件后再去校验该文件的内容是否含有该字符串,如果存在这样的文件,则输出相关信息。

import java.io.*;
import java.util.Scanner;

public class Program2 {
    public static void main(String[] args) {
        //1. 获取信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入扫描的文件夹:");
        String scanFile = sc.nextLine();
        System.out.println("请输入需要查找的内容:");
        String words = sc.nextLine();
        //2. 如果不是文件夹,输入有误
        File file = new File(scanFile);
        if (!file.isDirectory()) {
            System.out.println("输入的路径非法!");
            return;
        }

        //3. 扫描路径
        scanDire(file, words);
    }
    private static void scanDire(File root, String words) {
        //1.获取当前文件夹所有文件
        File[] files = root.listFiles();
        if (files == null) {
            //目录为空直接返回
            return;
        }
        // 2. 遍历文件
        for (File f : files) {
            if (f.isFile()) {
                //如果文件包含目标内容则打印信息
                if (containsWords(f, words)) {
                    try {
                        System.out.println(f.getCanonicalPath());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            } else if (f.isDirectory()) {
                //继续遍历
                scanDire(f, words);
            }
        }
    }
    private static boolean containsWords(File f, String words) {
        StringBuilder stringBuilder = new StringBuilder();
        try(Reader reader = new FileReader(f)) {
            while (true) {
                char[] chars = new char[1024];
                int len = reader.read(chars);
                if (len == -1) {
                    break;
                }
                stringBuilder.append(chars, 0, len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return stringBuilder.indexOf(words) != -1;
    }
}

现在我给出一个文件夹查找,里面有5个文本文件,其中35号文本文件含有aaa,现在我们需要查找这两个文件。

查找
🍇 运行后查找结果:

请输入扫描的文件夹:
D:\未见花闻\项目\文件IOFile类演示\查找
请输入需要查找的内容:
aaa
D:\未见花闻\项目\文件IOFile类演示\查找\3.txt
D:\未见花闻\项目\文件IOFile类演示\查找\5.txt

Process finished with exit code 0

🍊2.2.5复制普通文件

文件的复制需要知道源路径和目标路径,而源路径下必须是普通文件,然后就开始读取源路径的文件,将读到的数据写入到目标文件路径下即可。

import java.io.*;
import java.util.Scanner;

public class Program3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //1. 获取信息
        System.out.println("请输入源文件路径:");
        String src = sc.nextLine();
        System.out.println("请输入目标文件路径:");
        String goal = sc.nextLine();
        File srcFile = new File(src);
        if (!srcFile.isFile()) {
            System.out.println("输入的源文件路径非法!");
            return;
        }
        //2. 拷贝文件
        try (InputStream inputStream = new FileInputStream(srcFile)) {
            try (OutputStream outputStream = new FileOutputStream(goal)){
                while (true) {
                    byte[] bytes = new byte[1024];
                    int len = inputStream.read(bytes);
                    if (len == -1) {
                        break;
                    }
                    outputStream.write(bytes, 0, len);
                }
                System.out.println("拷贝成功!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

现在有两个文件夹,一个是源目录,另一个是目标目录,源目录下有一张图片文件,目标目录啥也没有,我们来尝试拷贝这两个文件。
源文件

🍇代码运行结果:

请输入源文件路径:
D:\未见花闻\项目\文件IOFile类演示\源目录\1.png
请输入目标文件路径:
D:\未见花闻\项目\文件IOFile类演示\目标目录\2.png
拷贝成功!

Process finished with exit code 0

🍇 运行后目标目录文件:
目标目录

我的文章写完了,关于文件IO相关操作你会了吗?


下期预告:初识计算机网络

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。