前述和需求说明
和之前写的 Python:基于MD5的文件监听程序 是同样的功能,就不啰嗦了,就是又写了一个java版本的,可以移步 python 版本去看一下,整个的核心思路是一样的。代码已上传Github
类说明
FileMd5.java 利用md5生成文件hash值
fileWalk.java 只是一个文件遍历的demo,没有被其他类调用
myFileListener.java 主程序,监控文件夹,用到了文件遍历,调用了FileMd5中的FileMd5类
代码
FileMd5.java
package myFileListener; import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.io.FileInputStream;
import java.io.IOException; public class FileMd5 {
public static String fileMd5(String inputFile) throws IOException{ int bufferSize = 1024*1024; //缓冲区大小
FileInputStream fileInputStream = null;
DigestInputStream digestInputStream = null; try {
//获取MD5的实例
MessageDigest messageDigest = MessageDigest.getInstance("MD5"); fileInputStream = new FileInputStream(inputFile); digestInputStream = new DigestInputStream(fileInputStream, messageDigest); //Creates a digest input stream, using the specified input stream and message digest. byte[] buffer = new byte[bufferSize]; //设置缓冲区,辅助读取文件,避免文件过大,导致的IO开销
while(digestInputStream.read(buffer)>0); //read: updates the message digest return int
// 获取最终的MessageDigest
messageDigest = digestInputStream.getMessageDigest();
// 拿到结果 return字节数组byte[] 包含16个元素
byte[] resultByteArray = messageDigest.digest(); return byteArrayToHex(resultByteArray); //转换byte 为 string 类型 }catch(NoSuchAlgorithmException e) {
return null;
}finally {
try {
digestInputStream.close();
fileInputStream.close();
}catch (Exception e) {
System.out.println(e);
}
}
} public static String byteArrayToHex(byte[] byteArray){
char[] hexDigits = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
//一个字节是八位二进制 也就是2位十六进制字符
char[] resultCharArray = new char[byteArray.length*2]; int index = 0;
for(byte b : byteArray){
resultCharArray[index++] = hexDigits[b>>> 4 & 0xf];
resultCharArray[index++] = hexDigits[b& 0xf];
}
return new String(resultCharArray);
}
}
myFileListener.java
package myFileListener; import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import myFileListener.FileMd5; /**
* @author jyroo
* myfilelistener
*/
@SuppressWarnings("unused")
public class myFileListener {
HashMap<String, String> hashmap = new HashMap<>(); //存放hash键值对
List<String> file_in = new ArrayList<String>();
List<String> file_ex = new ArrayList<String>();
@SuppressWarnings("static-access")
public void iteratorPath(String dir, List<String> file_in, List<String> file_ex) {
while(true) {
List<String> pathName = new ArrayList<String>(); //存放文件名
File file = new File(dir);
File[] files = file.listFiles(); //返回某个目录下所有文件和目录的绝对路径 return file[]
if(files != null) {
for(File each_file : files) {
if(each_file.isFile()) { // 如果是文件
int jui=2, juj=2;
if(file_in.size()!=0) {
jui = 0;
for(String strin : file_in) {
if(each_file.getName().indexOf(strin)==-1) {
jui = 0;
}
if(each_file.getName().indexOf(strin)!=-1) {
jui = 1;
}
}
}
if(file_ex.size()!=0) {
juj = 0;
for(String strex : file_ex) {
if(each_file.getName().indexOf(strex)!=-1) {
juj = 1;
}
}
if(juj==1||jui==0) {
continue;
}
pathName.add(each_file.getName()); //存储文件名 String file_path = each_file.getAbsolutePath(); //获取文件的绝对路径 try {
FileMd5 mymd5 = new FileMd5();
String md5_value = mymd5.fileMd5(file_path); //生成文件对应的hash值
if(hashmap.get(each_file.getName())==null) {
System.out.println("文件夹:" + dir + "中的文件:" + each_file.getName() + "为新建文件!时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
hashmap.put(each_file.getName(), md5_value); //以文件名作为key,hash值作为value存储到hashmap中
}
if(!hashmap.get(each_file.getName()).equals(md5_value)) {
System.out.println("文件夹:" + dir + "中的文件:" + each_file.getName() + "被更新!时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
hashmap.put(each_file.getName(), md5_value);
}
} catch (Exception e) {
System.out.println("发生 "+e+" 的错误!!时间为" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}
}
// }else if(each_file.isDirectory()) { //如果是文件夹
// //iteratorPath(each_file.getAbsolutePath()); //递归遍历
// }
}
}
try {
int juk;
for(String key : hashmap.keySet()) {
if(!pathName.contains(key)) {
System.out.println("文件夹:" + dir + "中的文件:" + key + "的文件已被删除!时间为:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
hashmap.remove(key);
}
}
}catch(Exception e) {
System.out.println(e);
}
}
}
} public static void main(String[] args) {
myFileListener file_walk = new myFileListener();
List<String> file_ex = new ArrayList<String>();
List<String> file_in = new ArrayList<String>();
file_ex.add(".rec");
//file_in.add("hi");
file_walk.iteratorPath("E:\\tmp\\", file_in, file_ex);
for(String key:file_walk.hashmap.keySet()){
System.out.println("Key: "+key+" Value: "+file_walk.hashmap.get(key));
}
} }
fileWalk.java
package myFileListener; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test; @SuppressWarnings("unused")
public class fileWalk {
List<String> pathName = new ArrayList<String>();
public void iteratorPath(String dir) {
File file = new File(dir);
File[] files = file.listFiles(); //listFiles是获取该目录下所有文件和目录的绝对路径 return file[]
if(files != null) {
for(File each_file : files) {
if(each_file.isFile()) {
pathName.add(each_file.getName());
}else if(each_file.isDirectory()) {
iteratorPath(file.getAbsolutePath());
}
}
}
} public static void main(String[] args) {
fileWalk file_walk = new fileWalk();
file_walk.iteratorPath("E:\\tmp\\");
for(String list : file_walk.pathName) {
System.out.println(list);
}
}
}