一文带你迅速掌握【文件操作】

文件IO操作—>操作硬盘

  • 1.文件系统操作:创建文件、删除操作、重命名文件、创建目录…
  • 2.文件内容操作:针对文件内容进行 读 和 写

1. 文件系统操作

Java 标准库,提供了一个 File 这个类

  1. 构造一个 File对象,构造过程中,可以使用 绝对路径/相对路径 进行初始化,这个路径指向的文件,可以是真实的,也可以是不存在~
File file = new File("test-dir/aaa/bbb");
  1. File 提供来了一些方法
    在这里插入图片描述

2. 文件内容操作

  1. 针对文本文件,提供了一组类,统称为 “字符流”(典型代表,Reader,Writer)
  2. 针对二进制文件,提供了一组类,统称为 “字节流” (典型代表,InputStream , OutputStream)

每种流对象,又分为两种

  • 输入的:Reader、InputStream
  • 输出的:Writer、OutputStrem

在这里插入图片描述

2.1 InputStream

在这里插入图片描述
通过源码可以看到 InputStream 是一个抽象类,是不能直接创建实例的,可以创建它的子类实例 FileInputStream
在这里插入图片描述
但是这里有一个重点:一定要记得 close,文件资源需要手动释放

这里的文件资源指的是 “文件描述符”
进程,是使用PCB这样的结构来表示的
1.pid
2.内存指针
3.文件描述符表
文件描述符表:就是记录了当前进程都打开了哪些文件,每次打开一个文件,就会在这个表里,申请到一个元素。这个表可以当成 一个数组,数组下标就是描述符,数组中的元素,就是这个文件在内核中的结构体的表示
由于,这个表长度有限制的,不能无休止的打开,但是又不释放,一旦满了,继续打开,就会打开失败~ 造成文件资源泄露


我们将代码写成如下,就不需要手动再写 close, 带有资源的 try 操作,会在 try 代码块结束后,自动执行 close 关闭操作 (是因为 InputStream 实现了 Closeable 接口)
在这里插入图片描述


public class IODemo3 {
    public static void main(String[] args) throws IOException {
        try (InputStream inputStream = new FileInputStream("f:/test.txt")) {
            // 读文件操作
            // read 一次返回一个字节,但是此处的返回值类型是 int
            while (true){
                int b = inputStream.read();
                if (b == -1){
                    // 读到末尾
                    break;
                }
                System.out.println(b);
            }
        }
    }
}

在这里插入图片描述

在这里插入图片描述


2.2 利用 Scanner 进行字符读取

public class IODemo4 {

    public static void main(String[] args) throws IOException {
        try (InputStream inputStream = new FileInputStream("f:/test.txt")) {
            try(Scanner scanner = new Scanner(inputStream,"UTF-8")){
                while (scanner.hasNext()){
                    String s = scanner.nextLine();
                    System.out.println(s);
                }
            }
        }
    }
}

在这里插入图片描述

2.3 outputStream

public class IODemo5 {
    public static void main(String[] args) {
        try(OutputStream outputStream = new FileOutputStream("f:/test.txt")){
            outputStream.write(97);
            outputStream.write(97);
            outputStream.write(97);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

在这里插入图片描述

2.4 Reader

在这里插入图片描述

public class IODemo6 {
    public static void main(String[] args) {
        try(Reader reader = new FileReader("f:/test.txt")){
            while (true){
                int c = reader.read();
                if (c == -1){
                    break;
                }
                System.out.println((char)c);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

在这里插入图片描述

3. 案例

遍历目录,在里面的文件内容中查找 包含 xxxx 信息的文件

采用简单粗暴的递归方式:

    1. 先去递归的遍历目录,比如给定一个 f:/ 去递归的把所有的文件都列出来
    1. 每次找到一个文件,都打开,并读取文件内容(得到String)
    1. 再判定要查询的词,是否在上述文件内容中存在,如果存在,就是要找的文件,打印出文件位置
package io;

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

public class IODemo7 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 1. 先让用户指定一个要搜索的目录
        System.out.println("请输入要扫描的根目录");
        File rootDir = new File(scanner.next());
        if (!rootDir.isDirectory()) {
            System.out.println("输入有误,您输入目录不存在");
            return;
        }

        // 2. 用户输入查询的词
        System.out.println("请输入要查询的词:");
        String word = scanner.next();

        //3. 递归的进行目录/文件的遍历
        scanDir(rootDir, word);
    }

    private static void scanDir(File rootDir, String word) {
        // 列出当前的 rootDir中的内容,没有内容,直接递归结束
        File[] files = rootDir.listFiles();
        if (files == null) {
            return;
        }
        // 目录有内容,遍历目录中的每个元素
        for (File f : files) {
            if (f.isFile()) {
                // 是普通文件
                String content = readFile(f);
                if (content.contains(word)) {
                    System.out.println(f.getAbsoluteFile() + "包含要查找的关键字");
                }

            } else if (f.isDirectory()) {
                // 是目录
                scanDir(f,word);
            } else {
                // 不是普通文件,也不是目录文件,直接跳过
                continue;
            }
        }

    }

    private static String readFile(File f) {
        // 读取文件的整个内容,返回出来
        // 使用字符流来读取,由于咱们匹配的是字符串,此处只能按照字符流,才有意义
        StringBuilder builder = new StringBuilder();
        try (Reader reader = new FileReader(f)) {
            // 一次读一个字符,把读到的结果拼装到 StringBuilder中,统一转换成 String
            while (true) {
                int c = reader.read();
                if (c == -1) {
                    {
                        break;
                    }
                }
                builder.append((char)c);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return builder.toString();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个想打拳的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值