[英]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.