WatchServiceクラスを使用したファイルモニタリングの概要


プロジェクトの中で1つのデータのインタラクティブな機能をすることを要求するため、大体外のシステムのためにいくつかのデータを本システムに導入して、データの中で大量のピクチャー、およびドキュメント、あるいはその他の資料に関連して、大きさはおよそ50-200 Mぐらいで、そのためftpを使ってインタラクティブに行うことを決定します.
まず、外部システムftpアカウントを提供し、ファイルサーバにアップロードします.
その後、本システムはファイルサーバの対応するフォルダを監視します.
本人がプロジェクトで使用しているのはWatchServiceクラスです.
1、プロジェクトの初期化後、ファイルモニタリングサービスとしてスレッドを開きます(ここでは、プロジェクトの他の機能に影響を与えないようにスレッドを再開することをお勧めします).
package com.*.*.modules.*.listener;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.*.*.modules.*.service.FileWatcherService;
@Component("ContextEventHandler") 
public class ContextEventHandler implements ApplicationListener {
	private static final Logger logger = Logger.getLogger(ContextEventHandler.class);
	@Resource
	private FileWatcherService fileWatcherService;
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if(event.getApplicationContext().getParent() == null){//root application context   parent,     .  
            //         , spring               。 
			logger.info("-------------        FTP      -------------");
			new Thread(new Runnable() {	
				@Override
				public void run() {
					try {
						fileWatcherService.handleEvents();
					} catch (Exception e) {
						logger.error("-------------          -------------", e);
					}
					
				}
			}).start();
        } 
	} 
}
2、

package com.*.*.modules.*.service;

import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.ArrayList;
import java.util.List;


import javax.annotation.Resource;


import org.apache.log4j.Logger;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * **      service
 * @author wuyp
 * @date 2017/11/25
 */
@Service("FileWatcherService")
public class FileWatcherService {
	@Resource
	...
	@Resource
	private ThreadPoolTaskExecutor executor;
	
	private final String uploadDir = Global.getConfig("uploadDir"); //      
	private final String backupDir = Global.getConfig("backupDir"); //      
	private final String unzipDir = Global.getConfig("unzipDir"); //      
	
	private WatchService watcher;  
	private static final Logger logger = Logger.getLogger(FileWatcherService.class);
	
    public FileWatcherService()throws IOException{ 
    	Path myDir = Paths.get(uploadDir);
    	logger.info("      "+uploadDir);
    	watcher = myDir.getFileSystem().newWatchService(); 
    	myDir.register(watcher, ENTRY_CREATE,ENTRY_DELETE);  //ENTRY_MODIFY
    }  
    
      public void handleEvents() throws Exception{ 
        while(true){  
        WatchKey key = watcher.take();
			for(WatchEvent> event : key.pollEvents()){  
				WatchEvent.Kind kind = event.kind();  
	            if(kind == OVERFLOW){//    lost or discarded  
	                continue;  
	            }  
	            WatchEvent e = (WatchEvent)event;  
	            /* Path fileName = e.context(); 
	             File file = fileName.toFile();*/
	            String filePath = uploadDir+e.context();
	            logger.info("      :"+kind.name()+",     :"+filePath);
	            if (kind == ENTRY_CREATE) {
	            	//           
	            	boolean fileIsCreateSuccess = fileIsCreateSuccess(filePath);
	            	if (fileIsCreateSuccess) {
	            		File file = new File(filePath);
	            		FileHandlingTask fileHandlingTask = new FileHandlingTask(file);
	            		executor.execute(fileHandlingTask);//          
				}
	 		  }
            }  
            if(!key.reset()){  
                break;  
            }  
		} 
    }
}

大まかなコードは、上記の通りです.開発中に発生したいくつかの問題について説明します.
1、プロジェクト初期化時にモニタリングサービスを開始する
     プロジェクトは単体アーキテクチャであるため、初期化時に他の機能を完成する必要があり、開始時に別のスレッドがなく、WebContextListenerで直接監視した結果、プロジェクトは走れなくなった.監視中はwhile(true)であり、後続の初期化が実行できないため、別のスレッドを開く必要がある.
2、ftpがファイルをアップロードした後、WatchServiceはすぐに監視できるが、この時ファイルがアップロードに成功したとは限らない.
     最初は、フォルダ権限、ファイル権限、またはftpアカウント権限だと思っていたが、最後に777権限を与えてもだめで、最後に証明はすべてではない.
    なぜなら、アップロードされたファイルが完全に成功せずにすぐに監視され、すぐにファイルをコピー、解凍処理するからです.その後は操作前に10 s眠り、最終的には  やはりたまに問題があります.大きなファイルのアップロードは10 sで十分ではないので、ファイルのアップロードが成功したと判断する必要があります(http://blog.csdn.net/w20228396/article/details/78646336)