Hutool操作和监听文件

简介: Hutool操作和监听文件

1 文件监听简单使用

很多时候我们需要监听一个文件的变化或者目录的变动,包括文件的创建、修改、删除,以及目录下文件的创建、修改和删除

1.1 WatchMonitor

在Hutool中,WatchMonitor主要针对JDK7中WatchService做了封装,针对文件和目录的变动(创建、更新、删除)做一个钩子,在Watcher中定义相应的逻辑来应对这些文件的变化。

1.2 内部应用

在hutool-setting模块,使用WatchMonitor监测配置文件变化,然后自动load到内存中。WatchMonitor的使用可以避免轮询,以事件响应的方式应对文件变化。

WatchMonitor提供的事件有:

  • ENTRY_MODIFY 文件修改的事件
  • ENTRY_CREATE 文件或目录创建的事件
  • ENTRY_DELETE 文件或目录删除的事件
  • OVERFLOW 丢失的事件

这些事件对应StandardWatchEventKinds中的事件。

下面我们介绍WatchMonitor的使用:

1.3 监听指定事件

package com.oldlu.transfer.message.util;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.watch.SimpleWatcher;
import cn.hutool.core.io.watch.WatchMonitor;
import cn.hutool.core.io.watch.Watcher;
import cn.hutool.core.lang.Console;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
/**
 * @author oldlu
 * @version 1.0
 * @date 2021/7/8 
 */
public class FileUtils {
    public static void main(String[] args) {
        File file2 = FileUtil.file("C:\\Users\\Administrator");
        //这里只监听文件或目录的修改事件(可以根据要求修改)
        WatchMonitor watchMonitor = WatchMonitor.create(file2, WatchMonitor.EVENTS_ALL);
//        WatchMonitor.createAll(file, new SimpleWatcher(){
//            @Override
//            public void onModify(WatchEvent<?> event, Path currentPath) {
//                Console.log("EVENT modify");
//            }
//        }).start();
        watchMonitor.setWatcher(new Watcher(){
            @Override
            public void onCreate(WatchEvent<?> event, Path currentPath) {
                Object obj = event.context();
                Console.log("创建:{}-> {}", currentPath, obj);
            }
            @Override
            public void onModify(WatchEvent<?> event, Path currentPath) {
                Object obj = event.context();
                Console.log("修改:{}-> {}", currentPath, obj);
            }
            @Override
            public void onDelete(WatchEvent<?> event, Path currentPath) {
                Object obj = event.context();
                Console.log("删除:{}-> {}", currentPath, obj);
            }
            @Override
            public void onOverflow(WatchEvent<?> event, Path currentPath) {
                Object obj = event.context();
                Console.log("Overflow:{}-> {}", currentPath, obj);
            }
        });
        //设置监听目录的最大深入,目录层级大于制定层级的变更将不被监听,默认只监听当前层级目录
        watchMonitor.setMaxDepth(3);
        //启动监听
        watchMonitor.start();
    }
}

1.4 监听全部事件

其实我们不必实现Watcher的所有接口方法,Hutool同时提供了SimpleWatcher类,只需重写对应方法即可。

同样,如果我们想监听所有事件,可以:

WatchMonitor.createAll(file, new SimpleWatcher(){
  @Override
  public void onModify(WatchEvent<?> event, Path currentPath) {
    Console.log("EVENT modify");
  }
}).start();

createAll方法会创建一个监听所有事件的WatchMonitor,同时在第二个参数中定义Watcher来负责处理这些变动。

1.5 延迟处理监听事件

在监听目录或文件时,如果这个文件有修改操作,JDK会多次触发modify方法,为了解决这个问题,我们定义了DelayWatcher,此类通过维护一个Set将短时间内相同文件多次modify的事件合并处理触发,从而避免以上问题。

WatchMonitor monitor = WatchMonitor.createAll("d:/", new DelayWatcher(watcher, 500));
monitor.start();

IO流相关

文件的拷贝

    // 文件的拷贝
    BufferedInputStream in = FileUtil.getInputStream("d:/桌面/HuTool学习.md");
    BufferedOutputStream out = FileUtil.getOutputStream("d:/桌面/HuTool学习复制.md");
    long copySize = IoUtil.copy(in, out, IoUtil.DEFAULT_BUFFER_SIZE);
    // 拷贝文件的大小
    System.out.println(copySize);
    System.out.println("拷贝成功");
    in.close();
    out.close();

文件类型判断

用于文件类型的判断,返回值为文件的类型

    File file = FileUtil.file("d:/桌面/HuTool学习.md");
    String type = FileTypeUtil.getType(file);
    //输出的是文件的格式
    Console.log(type);

2 文件的读取

//默认UTF-8编码,可以在构造中传入第二个参数做为编码
    FileReader fileReader = new FileReader("d:/桌面/HuTool测试.txt");
    String result = fileReader.readString();
    System.out.println(result);

3 文件的写入

FileWriter writer = new FileWriter("d:/桌面/HuTool测 试.txt");
    writer.write("添加文本",true);

实例:

** @Override
    public ResponseEntity<byte[]> download(String fileId) {
        QueryWrapper queryWrapper=new QueryWrapper();
        queryWrapper.eq("file_id",fileId);
        queryWrapper.orderByDesc("create_time");
        queryWrapper.last("limit 1");
        MeetingSignRecordFile meetingSignRecordFile = meetingSignRecordFileMapper.selectOne(queryWrapper);
        if (StringUtils.isBlank(meetingSignRecordFile.getPath())){
            System.out.println(downloadUrl + downloadPostfix + fileId);
            ResponseEntity<byte[]> forEntity = restTemplate.getForEntity(downloadUrl + downloadPostfix + fileId, byte[].class);
            byte[] body = forEntity.getBody();
            String filePath = System.getProperty("user.home") + "/jury/fileInfo/" + meetingSignRecordFile.getMc();
            FileWriter fileWriter=new FileWriter(filePath);
            fileWriter.write(body, 0, body.length);
            UpdateWrapper updateWrapper=new UpdateWrapper();
            meetingSignRecordFile.setPath(filePath);
            updateWrapper.eq("sign_form_id",meetingSignRecordFile.getSignFormId());
            meetingSignRecordFileMapper.update(meetingSignRecordFile,updateWrapper);
            return forEntity;
        }else{
            FileReader fileReader = new FileReader(meetingSignRecordFile.getPath());
            byte[] bytes = fileReader.readBytes();
            ResponseEntity<byte[]> responseEntity=new ResponseEntity<>(bytes,HttpStatus.OK);
            return responseEntity;
        }
    }**

4 文件追加

主要用于类似日志这种(此类只有在写入文件的时候打开文件,写入结束之后,此类不需要关闭

    File file = new File("d:/桌面/HuTool测试.txt");
    FileAppender appender = new FileAppender(file, 16, true);
    appender.append("lolly1023");
    appender.append("追加");
    appender.append("成功");
    appender.flush();
    appender.toString();

5 文件跟随

有时候需要启动线程来“监控文件的变化,类似于Linux下的tail -f命令

  Tailer tailer = new Tailer(FileUtil.file("d:/桌面/test.log"), Tailer.CONSOLE_HANDLER, 2);
  tailer.start();

实时打印文件变化的类

/**
 * 命令行打印的行处理器
 * 
 * @author oldlu
 * @since 4.5.2
 */
public static class ConsoleLineHandler implements LineHandler {
    @Override
    public void handle(String line) {
        Console.log(line);
    }
}

该方法会阻塞线程

6 文件名与扩展名

获取文件名

    File file = FileUtil.file("d:/桌面/HuTool学习.md");
    // HuTool学习.md
    String name = FileNameUtil.getName(file);
    System.out.println(name);

单独获取主文件名扩展名

    File file1 = FileUtil.file("d:/桌面/HuTool学习.md");
    // "HuTool学习"
    String name1 = FileNameUtil.mainName(file1);
    System.out.println(name1);
    // "md"
    String name2 = FileNameUtil.extName(file1);
    System.out.println(name2);


目录
相关文章
|
12月前
|
存储 Java Maven
如何使用Spring Boot和MinIO实现文件上传、读取、下载和删除的功能?
如何使用Spring Boot和MinIO实现文件上传、读取、下载和删除的功能?
1284 5
|
6月前
|
API
使用commons-io-2.0 API来实现监听文件变化
使用commons-io-2.0 API来实现监听文件变化
270 0
|
XML Java 数据格式
Flowable 服务任务执行的三种方式
Flowable 服务任务执行的三种方式
1287 0
|
XML Java 数据格式
JAVA如何监听XML文件?并处理数据
本文主要的内容,就是讲述,第三方客户端,在指定的文件夹生成了对应的xml文件,java程序需要监听对应的文件夹,并解析xml文件内容,转成javaBean,主要使用到了xjc生成对应的实体类,在经过监听文件变化,加载xml数据,转换成对应的bean实例,采用的技术有Spring boot、XJC、commons-io
238 0
JAVA如何监听XML文件?并处理数据
|
XML 数据格式
hutool读取xml文件
hutool读取xml文件
|
JavaScript
node.js: socket.io服务端和客户端交互示例
node.js: socket.io服务端和客户端交互示例
325 0
node.js: socket.io服务端和客户端交互示例
|
Java API
hutool文件监听
java工具学习
hutool实现监听文件变化
hutool实现监听文件变化