【JavaEE】文件操作和IO-目录扫描全文检索小程序

这篇具有很好参考价值的文章主要介绍了【JavaEE】文件操作和IO-目录扫描全文检索小程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

不知道说啥了,看看吧【JavaEE】文件操作和IO-目录扫描全文检索小程序

【JavaEE】文件操作和IO-目录扫描全文检索小程序

JavaEE & 文件操作和IO

在之前的学习中,基本上都是围绕内存展开的~

  • MySQL 主要是操作硬盘的

  • 文件IO也是是操作硬盘的~

IOinput output

1. 文件系统操作

  • 创造文件,删除文件,重命名文件,创建目录······
  • 一些操作没有权限也做不了~

1.1 路径

  • 就是我们的文件系统上的一个文件/目录的具体位置
    • 目录:文件夹
  • 计算机的目录是有层级结果的,即N叉树

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 我的代码库目录:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 那么这篇文章的源码所在的目录具体位置是什么呢?

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 所以,路径就是:D:/马库/marathon-april-2023/文件IO
    • 这是个绝对路径
      1. 绝对路径,即从盘符开始到具体文件/目录
      2. 相对路径,从指定目录开始到具体文件/目录
        • 要确认**(基准)工作目录**是什么~

而里面的src目录下有java文件,out目录里面就有class文件,同样有对应的路径

  1. / 分割,推荐!
  2. \ 分割的话要加转义字符\ , 即 \\
    • 一般只能适用于Windows
  3. …/ 代表这一级的上一个目录
  4. . 代表这当前目录(与后续目录要以 / 分割,即 . / )通常可以省略
  5. . . 代表当前目录的上一级目录(与后续目录要以 / 分割,即 . . /
    • . . / . . / 代表上一级目录的上一级目录~
  6. 默认源头的源头是“此电脑”目录,可以不写

绝对路径可以认为是以“此电脑”为工作目录的相对路径

  • 并且任何一个文件/目录,对应的路径,肯定是唯一的

    • 在LInux可能出现两个不同路径找到同一文件的情况~
    • 但是在Windows上不存在~
  • 路径与文件一一对应~

  • 路径为文件的身份

1.2 文本文件 与 二进制文件

  • 这个就是字面意思了

文本文件:

  • 存储字符(不仅仅是char类型)

二进制文件:

  • 存储什么都OK,因为任何数据都是以二进制为根本的

判断:

  • 记事本打开,是文本就是文本,是二进制就是二进制~
  1. .txt文件:文本 / 二进制,看你怎么创造的~
    【JavaEE】文件操作和IO-目录扫描全文检索小程序

  2. .java / .c 文件文本文件

    • 拖动到记事本里
      【JavaEE】文件操作和IO-目录扫描全文检索小程序
  3. .class / .exe 文件二进制文件~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. .jpg / mp3 二进制文件
    • 乱码,即把这一个个字节转化为字符型,而原本不是字符型的~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. pdf xlsx doc … : 二进制文件

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • csv excel的文本格式:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

1.3 文件系统操作

  • Java标准库提供了一个类:File
    • File对象代表着一个文件,是那个文件的抽象表示~
  • 硬盘上的文件 ==> 内存中的File对象 ==> 在内存上改变硬盘上的一些东西
1.3.1 构造File对象
  • 需要传一个文件路径为参数~
    • 这个文件可以存在也可以不存在

例如这张图片~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

【JavaEE】文件操作和IO-目录扫描全文检索小程序

1.3.2 使用File对象
  • 不手动常见文件是不会自动创建的
    • 不会再new的时候创建
序号 方法名 方法说明
1 String getParent() 返回 File 对象的父目录文件路径
2 String getName() 返回 FIle 对象的纯文件名称
3 String getPath() 返回 File 对象的文件路径
4 String getAbsolutePath() 返回 File 对象的绝对路径
5 String getCanonicalPath() 返回 File 对象的修饰过的绝对路径
6 boolean exists() 判断 File 对象描述的文件是否真实存在
7 boolean isDirectory() 判断 File 对象代表的文件是否是一个目录
8 boolean isFile() 判断 File 对象代表的文件是否是一个普通文件
9 boolean createNewFile() 根据 File 对象,自动创建一个空文件。成功创建后返 回 true
10 boolean delete() 根据 File 对象,删除该文件。成功删除后返回 true
11 void deleteOnExit() 根据 File 对象,标注文件将被删除,删除动作会到 JVM 运行结束时才会进行
12 String[] list() 返回 File 对象代表的目录下的所有文件名
13 File[] listFiles() 返回 File 对象代表的目录下的所有文件,以 File 对象表示
14 boolean mkdir() 创建 File 对象代表的目录
15 boolean mkdirs() 创建 File 对象代表的目录,如果必要,会创建中间目录
16 boolean renameTo(File dest) 进行文件改名,也可以视为我们平时的剪切、粘贴操作
17 boolean canRead() 判断用户是否对文件有可读权限
18 boolean canWrite() 判断用户是否对文件有可写权限

小小演示:

  1. 绝对路径
public static void main(String[] args) throws IOException {
    File file = new File("d:/马图/瞪眼.jpg");
    System.out.println(file.getParent());
    System.out.println(file.getName());
    System.out.println(file.getPath());
    System.out.println(file.getAbsoluteFile());
    System.out.println(file.getCanonicalFile());
}
  • IOException是IO操作的会抛出的常见异常
    • 是首查异常,也叫编译时异常

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 相对路径
    • 默认是与src目录的上一级的为工作目录~
    • 就是项目所在目录
    • 而不是src这一级

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 打印得出来这个文件不代表就存在这个文件~
  1. 是否存在?

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 性质,创造文件,删除文件
    • 是存在既不是目录又不是普通文件的文件的
    • 例如socket文件等等~
public static void main(String[] args) {
    File file = new File("./helloWorld.txt");
    System.out.println(file.exists());
    System.out.println(file.isDirectory());//是目录吗?(文件夹)
    System.out.println(file.isFile());//是文件吗?(普通文件)
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 创建与删除目录
public static void main(String[] args) {
    File file = new File("./helloWorld");
    if(!file.exists()) {
        file.mkdir();
    }
    System.out.println(file.exists());
    System.out.println(file.isFile());
    System.out.println(file.isDirectory());
}

make directory

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 路径转化为数组

获取目录里的所有文件/目录

  • list ==> 文件 /目录名数组
  • listFile ==> File对象 数组
public static void main(String[] args) {
    File file = new File("helloWorld");
    String[] results1 = file.list();
    File[] results2 = file.listFiles();
    System.out.println(Arrays.toString(results1));
    System.out.println(Arrays.toString(results2));
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 重命名
public static void main(String[] args) {
    File file = new File("helloWorld");
    file.renameTo(new File("HELLO_WORLD"));
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2. 文件内容操作

  • 针对文件内容进行 读 与 写

  • 文件操作依赖于一些类,或者说是多组类

    1. 文本 ==> ”字符流“
    2. 二进制 ==> “字节流”

“流”:

  • 数据的运输像河流一样,流向哪,从哪流来~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.1 获取文件输入流InputStream(字节流)

public static void main(String[] args) throws IOException {
    InputStream inputStream = new FileInputStream("HELLO_WORLD");
		
    //coding

    inputStream.close();

}

有了输入流,就相当于你有了“介质”

  • 相当于打开文件,文件的信息可以出来

关闭输入流

  • 相当于关闭文件
  • 如果不关闭,可能会导致,文件资源泄露 ===>
  • 进程里有个文件描述符表,一旦打开文件多了,这个表可能会爆了,导致机器出问题!
  • Java的对象,没用了会自动释放,但是这里的流对象并不会!!!

正确的写法:(利用finally保证关闭能够进行)

  • try括号内为打开文件操作,默认finally关闭文件~
    • try with resources操作
public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("HELLO_WORLD/123.txt")) {

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • InputStream实现Closeable接口,那么就可以这样操作~
    • 这就是try with resource操作的要求
    • 注意:后续内容都是以这种方式打开与隐式关闭文件的
      【JavaEE】文件操作和IO-目录扫描全文检索小程序

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.1.1 read方法
  • 只能说文件里有个指针指着读在哪了,并不是读了后原文件就删了~
方法名 方法说明
int read() 一次读一个字节并返回,返回-1代表读完了
int read(byte[] b) 填满此数组为止,返回-1表示读完(可能填不满)
int read(byte[] b, int off, int len) 填满此数组的[off, off + len)为止,返回-1表示读完(可能填不满)
  • 在java对此方法的描述中提到:返回的字节转化为int类型,范围是0 - 255

手写一些数据:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.1.2 不带参数的read方法
public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("HELLO_WORLD/123.txt")) {
        int b = 0;
        do {
            b = inputStream.read();
            System.out.println(b);
        }while(b != -1);

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 测速结果:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 对于中文:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 测试结果:
    • 不是说一个中文 ==> 一个char字符 两个字节吗,为什么这里是三个字节一个汉字
    • 那是因为Unicode每个字符是两个字节
    • UTF-8汉字是三个字节,其他字符一个字节~
      • 我编译器无脑全设置UTF-8了
    • 而读取的内容可没有规定就是Java的char类型呀~
      • 但是我们可以通过一些手段翻译这个东西,后面讲~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 字符对应表 - 查询网站:查看字符编码(UTF-8) (mytju.com)

【JavaEE】文件操作和IO-目录扫描全文检索小程序

E9 : 233 A9 : 169 AC : 172 ················

完美对应~

2.1.3 给定数组的read方法
public static void main(String[] args) {
    try(InputStream inputStream = new FileInputStream("HELLO_WORLD/123.txt")) {
        byte[] bytes = new byte[9];
        System.out.println(inputStream.read(bytes));
        System.out.println(Arrays.toString(bytes));


    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 测试结果:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 咋变负数了?

    • 因为读取到的字节仍然是 -128 - 127 的
    • 只不过刚才返回int类型的是无符号的~
  • 如何翻译呢?

    • 用String的构造方法~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.2 获取文件输出流OutputStream(字节流)

public static void main(String[] args) {
    //每次打开输出流,都会清空文件内容~
    try(OutputStream outputStream = new FileOutputStream("HELLO_WORLD/123.txt")) {
        

    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • 每次打开文件,会清空原内容!
    【JavaEE】文件操作和IO-目录扫描全文检索小程序
2.2.1 write方法
方法名 方法说明
void write(int b) 传入一个int型,内部强行转化为byte型
void write(byte[] b) 将整个字节数组写入文件中
int write(byte[] b, int off, int len) 将字节数组的[off, off + len)部分写入文件中
void flush() 重要:我们知道 I/O 的速度是很慢的,所以,大多的 OutputStream 为 了减少设备操作的次数,在写数据的时候都会将数据先暂时写入内存的 一个指定区域里,直到该区域满了或者其他指定条件时才真正将数据写 入设备中,这个区域一般称为缓冲区。但造成一个结果,就是我们写的 数据,很可能会遗留一部分在缓冲区中。需要在最后或者合适的位置, 调用 flush(刷新)操作,将数据刷到设备中。
  • flush很重要,在关闭之前没有flush,文件内容就无法得以更新
2.2.2 write 传入单个字节的构造方法
public static void main(String[] args) {
    //每次打开输出流,都会清空文件内容~
    try(OutputStream outputStream = new FileOutputStream("HELLO_WORLD/123.txt")) {

        outputStream.write(1);
        outputStream.write(2);
        outputStream.write(3);
        outputStream.write(4);
        outputStream.flush();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.2.3 write 传入字节数组的构造方法
public static void main(String[] args) {
    //每次打开输出流,都会清空文件内容~
    try(OutputStream outputStream = new FileOutputStream("HELLO_WORLD/123.txt")) {

        outputStream.write(new byte[]{1, 2, 3, 4, 5, 6, 7});
        outputStream.flush();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.3 字符流 Reader 与 Writer

2.3.1 Reader的读方法
  • 对比于字节流,这里读的是字符,读进字符数组~
    public static void main(String[] args) throws FileNotFoundException {
        try(Reader reader = new FileReader("HELLO_WORLD/123.txt")) {
            char ch = (char)reader.read();
            char[] chars = new char[7];
            reader.read(chars);
            System.out.println(ch);
            System.out.println(chars);
            int c = 0;
            do {
                c = reader.read();
                System.out.println((char)c);
            }while (c != -1);
        } catch (IOException e) {
            e.printStackTrace();
        }

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 测试结果:
    • 同样read返回-1,代表读完了~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

2.3.2 Writer的写操作
  • 对比于字节流,这里写入的是字符,字符数组,或者字符串~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

    public static void main(String[] args) {
        try(Writer writer = new FileWriter("HELLO_WORLD/123.txt")) {
            writer.write('0');
            writer.write(new char[]{'1', '2', '3', '4', '5', '6'});
            writer.write("789");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
  • 写操作跟字节流一样,无此文件,自动创建~

  • 并且还会清空原内容

  • 测试结果:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

3. 小程序练习:全文检索

  • 就是遍历目录,并在文件内容中查找信息

【JavaEE】文件操作和IO-目录扫描全文检索小程序

接下来以简单粗暴的方式去实现~

3.1 控制台输入根目录与关键字

public static void main(String[] args) throws IOException {
    Scanner scanner = new Scanner(System.in);
    System.out.print("请输入要扫描的根目录:");
    String root = scanner.next();
    File file = new File(root);
    if(!file.isDirectory()) { // 1. 目录不存在 2. 不是目录
        System.out.println("输入错误");
        return;
    }
    System.out.print("请输入要查询的词:>");
    String words = scanner.next();
    scan(file, words);//扫描
}
  1. 根据根目录构造File对象
  2. 如果这个file对象不是目录或者不存在的话,则说明输入错误,直接返回退出程序
  3. 如果是目录,输入要关键字
  4. 调用scan方法对目录进行扫描(自己实现)

3.2 scan递归方法

  • n叉树就得写循环来递归了
  • 如果是扫描到二进制文件,我们也不指望里面有我们要的文本,因为二进制一般存放一些后端数据信息,并不是给人看的,不是观赏性的,但是二进制文件还是可能会读到的~
  • 记得设立递归出口,死递归会导致栈溢出
public static void scan(File file, String words) throws IOException {
    File[] files = file.listFiles();
    if(files == null) { 
        // 这里空目录对应的并不是空数组!是null~
        return;
    }else {
        for (int i = 0; i < files.length; i++) {
            File f = files[i];
            if(f.isFile()) {
                String content = readAll(f);
                if(content.contains(words)) {
                    System.out.println(f.getCanonicalFile());
                }
            }
            if(f.isDirectory()) {
                scan(f, words);
            }
            //两种都不是的其他文件,就不能读~
        }
    }

}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

3.3 readAll读取文件方法

  • 利用StringBuilder拼接字符串~
    • 用Reader字符流读取数据~
    • 对于Java,这些流对象只是读取方式,对文件是二进制还是文本没有要求
  • 最终返回
public static String readAll(File f) {
    StringBuilder stringBuilder = new StringBuilder();
    try (Reader reader = new FileReader(f)){
        while(true) {
            int c = reader.read();
            if(c == -1) {
                break;
            }
            stringBuilder.append((char)c);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return stringBuilder.toString();
}

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 堆溢出~

【JavaEE】文件操作和IO-目录扫描全文检索小程序

3.4 测试

  • 测试用例:
    • 如果文件数量多,内容多,以此法会卡的半死
    • 到时候我们学习一下“倒排索引”这种数据结构,可能能够很好地优化!

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  1. 根目录是:d:/马库/marathon-april-2023
  2. 关键字是:马大帅
  • 测试结果:

【JavaEE】文件操作和IO-目录扫描全文检索小程序

  • 测试结果正常!
    • 另外两个可能是其他项目里提到了这个关键字 ^ V ^

文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆

文件操作的讲解告一段落,后面也会涉及到哦!

实践才是最好的学习!文章来源地址https://www.toymoban.com/news/detail-489851.html


到了这里,关于【JavaEE】文件操作和IO-目录扫描全文检索小程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 17、全文检索 -- Elasticsearch -- 使用 反应式 RestClient (ReactiveElasticsearchClient)操作 Es 服务器(增、删、查 :索引库和文档)

    Elasticsearch 所提供 RestHighLevelClient 本身提供了 【同步编程】 和 【异步编程】两种模型。 Elasticsearch 官方并未提供反应式的 RestClient : 因此 Spring Data Elasticsearch 额外补充了一个 ReactiveElasticsearchClient,用于提供反应式API支持, ReactiveElasticsearchClient 相当于 RestHighLevelClient 的反应式

    2024年04月28日
    浏览(46)
  • 18、全文检索--Elasticsearch-- SpringBoot 整合 Spring Data Elasticsearch(异步方式(Reactive)和 传统同步方式 分别操作ES的代码演示)

    启动命令行窗口,执行:elasticsearch 命令即可启动 Elasticsearch 服务器 三种查询方式解释: 方法名查询: 就是全自动查询,只要按照规则来定义查询方法 ,Spring Data Elasticsearch 就会帮我们生成对应的查询语句,并且生成方法体。 @Query 查询 : 就是半自动查询, 按照 S

    2024年03月12日
    浏览(64)
  • 全文检索-Elasticsearch-进阶检索

    本文记录谷粒商城高级篇的 Elasticsearch 进阶检索部分,续上之前记录的 Elasticsearch入门篇。 ES 支持两种基本方式检索 : 一个是通过使用 REST request URI 发送搜索参数(uri + 检索参数) 另一个是通过使用 REST request body 来发送它们(uri + 请求体) 请求体中写查询条件,语法: 示例

    2024年02月03日
    浏览(87)
  • 【全文检索】sqlite-fts4和pgsql的全文检索对比

    因为是Android项目,老系统中的全文检索是采用sqlite自带的fts4,然而后续由于地图要素全部转为线上,全文检索也需要同步在线查询,所以将整个全文检索的功能迁移到pgsql中。目前这块功能基本结束,这里来对两种全文检索方案做一个对比总结。 相比与fts5,fts4的好处是原生

    2024年02月05日
    浏览(45)
  • 全文检索-Es-初步检索(三)

    #为jmeter返回的结果 jmeter测试结果 请求头 http请求 put 返回结果 再次发送请求 post不带/带id保存 不带id 结果 二次请求结果 带id保存 结果 二次请求结果 结论 发送请求 查询-查看结果树 增加判断,确定是否修改 结果 查看修改是否成功 结果 更新文档 post/put带_update的请求(会比

    2024年02月14日
    浏览(43)
  • Elasticsearch 全文检索 分词检索-Elasticsearch文章四

    https://www.elastic.co/guide/en/enterprise-search/current/start.html https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-match-query.html Full text Query中,我们只需要把如下的那么多点分为3大类,你的体系能力会大大提升 很多api都可以查得到,我们只要大概知道有支持哪些功能 Elasticsearch 执行

    2024年02月14日
    浏览(52)
  • Lucene全文检索

    Lucene 是一个基于 Java 的全文信息检索工具包,目前主流的搜索系统 Elasticsearch 和 solr 都是基于 lucene 的索引和搜索能力进行。 Solr与Lucene的区别: Solr和Lucene的本质区别三点:搜索服务器,企业级和管理。 Lucene本质上是搜索库,不是独立的应用程序,而Solr是。 Lucene专注于搜索

    2024年02月09日
    浏览(46)
  • elasticsearch全文检索

    传送门 best_fields 传送门 most_fields 当查询多字段包含相同文本以不同方式分词的时候此参数最有用, 传送门 cross_fields phrase和phrase_prefix 传送门 传送门

    2024年02月07日
    浏览(46)
  • MySQL中文全文检索

    常规数据库搜索都是用 like 语句,但是like 语句是不能利用索引的,查询效率极其低下。这也就是为什么很多功能都只提供标题搜索的原因,因为如果搜索内容,几万数据就跑不动了。 Mysql 全文索引是专门为了解决模糊查询提供的,可以对整篇文章预先按照词进行索引,搜索

    2024年02月14日
    浏览(44)
  • ElasticSearch-全文检索

    https://www.elastic.co/cn/what-is/elasticsearch 全文搜索属于最常见的需求,开源的Elasticsearch是目前全文搜索引擎的首选。 它可以快速地储存、搜索和分析海量数据。 维基百科、StackOverflow、Github都采用它。 Elastic的底层是开源库Lucene。但是,你没法直接用Lucene,必须自己写代码去调用

    2024年04月17日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包