簡體   English   中英

在沒有WatchService的情況下檢測Java中的文件更改

[英]detect file changes in Java without WatchService

我創建了一個文件檢查器,該檢查器每隔X秒檢查一次文件是否有更改。 問題是,如果我使用WatchService檢查文件,即使我touch file它也會發送修改事件。 我可以檢查file.lenght ,但是如果我所做的更改未更改文件大小怎么辦? 有什么辦法可以檢測文件更改嗎?

這是我的代碼(我使用lastModified()方法有一段時間)

class Checker implements Runnable {

static Logger log = Logger.getLogger(Monitor.class.getName());
private static final long DEFAULT_CHECK_INTERVAL = 5000; //5 sec
private static SimpleDateFormat dataFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");    
private File file;
private long checkInterval;

public Checker(String path, long checkInterval) throws Exception {
    this.file = new File(path);
    this.checkInterval = checkInterval > 1000 ? checkInterval : DEFAULT_CHECK_INTERVAL;
}

private JSONObject loadConfig() {
    JSONObject conf = null;
    try(BufferedReader reader = new BufferedReader(new FileReader(this.file));) {

        StringBuilder bldr = new StringBuilder((int) this.file.length());
        String line = null;

        while((line = reader.readLine()) != null) {
            bldr.append(line);
        }

        conf = new JSONObject(bldr.toString());

            Thread.sleep(this.checkInterval);

    } catch (Exception e) {
        log.error(e);
    }
    return conf;
}   

@Override
public void run() {
    long modDate = 0;

    while (true) {
        long lastModified = this.file.lastModified();
        JSONObject conf = loadConfig();
        if (lastModified != modDate) {
            modDate = lastModified;
            log.warn("File changed at " + dataFormat.format(lastModified));
            log.info(conf.get("name") + ", " + conf.get("company"));                
        }
        log.info("no chenges");         

    }

}

public class Monitor {

    public static void main(String[] args) throws Exception {
        new Thread(new Checker("/home/arno/test/config.json", 2000)).start();      
    }
}

也許Java NIO可以提供幫助

BasicFileAttributes attr = Files.readAttributes(file,BasicFileAttributes.class); System.out.println(“ lastModifiedTime:” + attr.lastModifiedTime());

在其他目錄中保留該文件的副本。

例如,我們在Desktop上擁有文件,在C:維護文件的副本,並檢查是否有任何差異。

File source = new File(""C://Desktop//filename.txt");
File dest = new File("C://temp//cache-filename.txt");
try {
    FileUtils.copyDirectory(source, dest);
} catch (IOException e) {
    e.printStackTrace();
}

然后維護一個計時器,每次都打電話給您。

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
  @Override
  public void run() {
  if(comapreTwoFiles("C://temp//cache-filename.txt", "C://Desktop//filename.txt")){
    System.out.println("File is changed");
    //change your cache file
    }
  }
}, 2*60*1000, 2*60*1000);
public boolean compareTwoFiles(String path1, String path2)
            throws IOException {

    File file1 = new File(path1);
    File file2 = new File(path2);

    BufferedReader br1 = new BufferedReader(new FileReader(file1));
    BufferedReader br2 = new BufferedReader(new FileReader(file2));

    String thisLine = null;
    String thatLine = null;

    List<String> list1 = new ArrayList<String>();
    List<String> list2 = new ArrayList<String>();

    while ((thisLine = br1.readLine()) != null) {
        list1.add(thisLine);
    }
    while ((thatLine = br2.readLine()) != null) {
        list2.add(thatLine);
    }

    br1.close();
    br2.close();

    return list1.equals(list2);
}

使用MD5的校驗和文件

public class MD5 {
    public static String getMD5(String input) {
        try {
            byte[] thedigest = MessageDigest.getInstance("MD5").digest(input.getBytes("UTF-8"));
            BigInteger number = new BigInteger(1, thedigest);
            String hashtext = number.toString(16);
            // Now we need to zero pad it if you actually want the full 32 chars.
            while (hashtext.length() < 32) {
                hashtext = "0" + hashtext;
            }
            return hashtext;
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    public static boolean checksum(String filePath, String hashCode) {
        try {
            return getFileHash(filePath).equals(hashCode);
        } catch (Exception ex) {
            return false;
        }
    }
    public static String getFileHash(String filePath) {
        InputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
            byte[] buffer = new byte[1024];
            MessageDigest complete = MessageDigest.getInstance("MD5");
            int numRead;
            do {
                numRead = fis.read(buffer);
                if (numRead > 0) {
                    complete.update(buffer, 0, numRead);
                }
            } while (numRead != -1);
            byte[] b = complete.digest();
            String result = "";
            for (int i = 0; i < b.length; i++) {
                result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
            }
            return result;
        } catch (IOException | NoSuchAlgorithmException ex) {
            Logger.getLogger(MD5.class.getName()).log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException ex) {
                Logger.getLogger(MD5.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

您可以檢查MD5校驗和而不是文件大小:

    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.security.MessageDigest;

    public class Main {

        public static byte[] getMD5Checksum(String filename) throws Exception {
            InputStream fis = new FileInputStream(filename);
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[1024];
            int aux;
            do {
                aux = fis.read(buffer);
                if (aux > 0) {
                    md.update(buffer, 0, aux);
                }
            } while (aux != -1);
            fis.close();
            return md.digest();
        }

        private static String toHexString(byte[] bytes) {
            StringBuilder sb = new StringBuilder(bytes.length * 2);
            for (byte b : bytes)
                sb.append(String.format("%02x", b & 0xff));
            return sb.toString();
        }

        public static void main(String args[]) throws Exception {
            System.out.println(toHexString(getMD5Checksum("/Users/irineuantunes/Desktop/testFile.txt")));
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM