| | |
| | | package org.springblade.mdm.machinefile.filewatch; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.io.IOException; |
| | |
| | | import java.util.concurrent.Executors; |
| | | |
| | | import static java.nio.file.StandardWatchEventKinds.*; |
| | | import com.google.common.cache.Cache; |
| | | import com.google.common.cache.CacheBuilder; |
| | | @Slf4j |
| | | @Service |
| | | public class FileWatcherService { |
| | | |
| | | private final ExecutorService executor = Executors.newCachedThreadPool(); |
| | | private final Map<Path, WatchService> watchServices = new HashMap<>(); |
| | | private final Map<Path, FileChangeListener> listeners = new HashMap<>(); |
| | | |
| | | Cache<Path, FileState> fileStates = CacheBuilder.newBuilder() |
| | | .maximumSize(10) // 最大容量3 |
| | | .build(); |
| | | enum FileState { |
| | | CREATED, MODIFIED, STABLE |
| | | } |
| | | |
| | | public interface FileChangeListener { |
| | | void onFileCreated(Path filePath); |
| | |
| | | try { |
| | | while (true) { |
| | | WatchKey key = watchService.take(); |
| | | |
| | | for (WatchEvent<?> event : key.pollEvents()) { |
| | | WatchEvent.Kind<?> kind = event.kind(); |
| | | |
| | |
| | | Path fileName = ev.context(); |
| | | Path fullPath = directory.resolve(fileName); |
| | | |
| | | FileState currentState = fileStates.getIfPresent(fullPath); |
| | | currentState = (currentState == null) ? FileState.STABLE : currentState; |
| | | |
| | | FileChangeListener currentListener = listeners.get(directory); |
| | | if (currentListener == null) break; |
| | | |
| | | if (kind == ENTRY_CREATE) { |
| | | if (currentState != FileState.CREATED) { |
| | | log.info("新文件创建: {}", fullPath); |
| | | fileStates.put(fullPath, FileState.CREATED); |
| | | } |
| | | currentListener.onFileCreated(fullPath); |
| | | } else if (kind == ENTRY_MODIFY) { |
| | | currentListener.onFileModified(fullPath); |
| | | if (currentState == FileState.CREATED) { |
| | | // 忽略创建后的第一次修改 |
| | | log.info("文件创建时的修改事件,忽略: {}", fullPath); |
| | | fileStates.put(fullPath, FileState.STABLE); |
| | | } else { |
| | | currentListener.onFileModified(fullPath); |
| | | } |
| | | } else if (kind == ENTRY_DELETE) { |
| | | currentListener.onFileDeleted(fullPath); |
| | | } |