JavaEE:文件内容操作练习(三)

文章目录


文件内容操作练习

练习1

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

java 复制代码
package javaEE.fileIO;

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

public class O {

    private static void scan(File currentFile, String key) {
        if (!currentFile.isDirectory()) {
            return;
        }
        File[] files = currentFile.listFiles();
        if (files == null || files.length == 0) {
            return;
        }
        for (File f : files) {
            if(f.isFile()) {
                // 针对普通文件进行处理,判定文件名是否符合要求并提示用户删除
                doDelete(f,key);
            } else {
                scan(f,key);
            }
        }
    }

    private static void doDelete(File f,String key) {
        if(!f.getName().contains(key)) {
            //文件名中不包含指定的关键字
            return;
        } else {
            // 提示用户是否要删除
            Scanner scanner = new Scanner(System.in);
            System.out.println(f.getAbsolutePath() + "确认删除?Y/N");
            String choice = scanner.next();
            if(choice.equals("Y") || choice.equals("y")) {
                f.delete();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("请输入要搜索的路径");
        Scanner scanner = new Scanner(System.in);
        String rootPath = scanner.next();
        File rootFile = new File(rootPath);
        if (!rootFile.isDirectory()) {
            System.out.println("输入的路径不存在");
            return;
        }
        System.out.println("请输入要删除的文件名字的关键字");
        String key = scanner.next();

        // 进行递归查找
        scan(rootFile, key);
    }
}

代码运行前:

代码运行后:

练习2

进行普通文件的复制.

java 复制代码
package javaEE.fileIO;

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

public class P {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入原文件的路径:");
        String srcPath = scanner.next();
        File srcFile = new File(srcPath);
        // 原文件需要确保路径存在,并且还要是一个文件
        if(!srcFile.isFile()) {
            System.out.println("原文件路径有误!");
            return;
        }
        System.out.println("请输入目标文件的路径");
        String destPath = scanner.next();
        File destFile = new File(destPath);
        // 目标文件需要确保目录存在
        if(!destFile.getParentFile().isDirectory()) {
            System.out.println("目标文件的路径有误");
            return;
        }
        // try()里可以写多个对象,多个对象的构造过程使用 ; 分隔
        try(InputStream inputStream = new FileInputStream(srcFile);
            OutputStream outputStream = new FileOutputStream(destFile)) {
            while (true) {
                byte[] buffer = new byte[1024];
                int n = inputStream.read(buffer);
                if(n == -1) {
                    break;
                }
                // 这里一定要指定区间,因为在最后一次从文件中读数据时,不一定是1024个字节!!
                outputStream.write(buffer,0,n);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行前:

运行后:

练习3

扫描指定路径,并找到名称或者内容中包含指定字符的所有普通文件(不包含目录)

java 复制代码
package javaEE.fileIO;

import java.io.*;
import java.nio.file.Files;
import java.util.Scanner;

public class Q {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要搜索的目录");
        String rootPath = scanner.next();
        File rootFile = new File(rootPath);
        if (!rootFile.isDirectory()) {
            System.out.println("要搜索的路径有误!");
            return;
        }
        System.out.println("请输入要搜索的查询词:");
        String key = scanner.next();

        // 进行查询
        scan(rootFile, key);
    }

    private static void scan(File rootFile,String key) {
        if(!rootFile.isDirectory()) {
            return;
        }
        File[] files = rootFile.listFiles();
        if(files == null || files.length == 0) {
            return;
        }
        for (File f: files) {
            if(f.isFile()) {
                // 进行查询
                doSearch(f,key);
            } else {
                // 进行递归
                scan(f,key);
            }
        }
    }
    private static void doSearch(File f,String key) {
        StringBuilder stringBuilder = new StringBuilder();
        // 打开文件,读取文件内容,判定文件内容是否包含key
        try(Reader reader = new FileReader(f)) {
            char[] buffer = new char[1024];
            while (true) {
                int n = reader.read(buffer);
                if(n == -1) {
                    break;
                }
                String s = new String(buffer,0,n);
                stringBuilder.append(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(stringBuilder.indexOf(key) == -1) {
            // 没找到
            return;
        }
        // 找到了
        System.out.println("找到匹配的文件" + f.getAbsolutePath());
    }
}

运行结果

此处这里的代码逻辑,效率是非常低的,每次查询,都会涉及到大量的硬盘IO操作.

这种思路,不能适应频繁查询的场景,也不能适应目录中文件数目特别多,特别大的场景.

这种基于内容的查询,其实也是存在的,比如说搜索引擎.

搜索引擎在进行搜索的过程,也就是在文件中查找内容是否被包含的过程.

搜索出来的结果其实就是一些html文件.

这些html文件里面一定是包含你的查询词(或者和你的查询词有关联)

上图是在数以十亿,数以百亿的html中,找到了30w个结果.

搜索引擎这样的场景,不能通过上述"遍历文件"的方式实现.

其中最核心的优化,就是引入了神奇的数据结构"倒排索引".提前把所有的文件里面的内容都分析好,分析出一个文件中,包含哪些词,然后基于这个结果,得到另一份数据,每个词,都在哪些文件中包含着.

实际工作中,也会用到一些"自定制的搜索引擎".

比如,我们自己的代码中,产生大量的日志,把这些日志,导入到自己搭建的搜索引擎中(用到一些业界成熟的方案,比如ES这种),从而快速查找.

本文到这里就结束啦~

相关推荐
三8446 小时前
Java 模板注入(FreeMarker)· 04 · 利用与绕过:payload 全集
java·web安全·freemarker·payload
leikooo7 小时前
ARTS 0913: 双栈互补实现队列、CIDR 聚合化解路由膨胀与 AI 作弊串通绝非偶然 Bug
java·链表·个人开发
星间都市山脉7 小时前
Android16 SystemService.onBootPhase 调用时机
android·java·linux·windows·ubuntu
swithun7 小时前
不用 WebView,我用 Kotlin + Compose Multiplatform 重写 Mermaid,并做了 2048 组对拍
android·开源·kotlin
深入云栈7 小时前
Netty 4.2.x 源码深度解析 (十三):Epoll 传输 —— Linux 高性能 IO 的 Netty 实现
java·后端
ynchyong7 小时前
Linux nohup 后台服务合并标准错误输出到一个文件
java·linux·运维
用户3126874877207 小时前
Lombok 的 @Data 到底怎么工作的?Java 注解处理器实战全链路拆解
java
AI吃大瓜7 小时前
人脸检测和行人检测4:Android实现YOLOv8 YOLO11 YOLO26人脸检测和人体检测(含源码,可实时检测)
android·yolo·人脸检测·人体检测·行人检测·yolo26
与海boy7 小时前
Prompt模版
android·prompt
小羊没烦恼!8 小时前
Memory 记忆设计讨论:为什么 Agent Memory 不能只靠向量数据库?
java·开发语言·windows·算法·c#