java文件备份_定时自动备份文件(java)
demo背景:由于同事说Excel表格在写着东西又突然被还原到之前的内容了,后面写的内容全部不见了。刚好最近自己在学习java,为此就用java写了一个小程序,这个小程序的功能比较简陋,纯属个人练习java某些语法点所用,具体如下:
1.可以指定需要备份的文件、和备份到哪个文件目录以及指定备份时间间隔;
2.只备份最新的文件,如果曾经已经存在过(也就是说文件被未知原因或人为恢复至前面的内容),则不备份,同时给予提示;
不足:
1.只能备份保存后的文件;
2.不支持大文件;
3.不支持备份目录;
4.不支持自动清理过期的备份文件;
实现原理:
1.通过生成文件的MD5值识别,并当做key添加进HashMap集合里面;
2.按一定时间段获取文件的MD5值,看是否改变,如果改变,并且HashMap里面的key没有相应的MD5值,则添加进集合。同时,把对应的文件备份。反之,不备份。
============================================================
1.获取文件MD5类(网上找的,出处暂时无从考证)
package md5offile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/** * Md5校验工具类 * @author Fengwx */
public class MD5Util {
public static void main(String[] args){
System.out.println(getFileMD5(new File("D:/javaTest/c/c.txt")));
System.out.println(getFileMD5(new File("D:/javaTest/a/b/c/abc")));
}
private static final char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f'};
/** * Get MD5 of a file (lower case)
* @return empty string if I/O error when get MD5
*/
public static String getFileMD5(File file) {
FileInputStream in = null;
try {
in = new FileInputStream(file);
FileChannel ch = in.getChannel();
return MD5(ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()));
} catch (FileNotFoundException e) {
return "";
} catch (IOException e) {
return "";
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// 关闭流产生的错误一般都可以忽略
}
}
}
}
/** * MD5校验字符串 * @param s String to be MD5
* * @return 'null' if cannot get MessageDigest
* */
private static String getStringMD5(String s) {
MessageDigest mdInst;
try {
// 获得MD5摘要算法的 MessageDigest 对象
mdInst = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return "";
}
byte[] btInput = s.getBytes();
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int length = md.length;
char str[] = new char[length * 2];
int k = 0;
for (byte b : md) {
str[k++] = hexDigits[b >>> 4 & 0xf];
str[k++] = hexDigits[b & 0xf];
}
return new String(str);
}
private static String getSubStr(String str, int subNu, char replace) {
int length = str.length();
if (length > subNu) {
str = str.substring(length - subNu, length);
} else if (length < subNu) {
// NOTE: padding字符填充在字符串的右侧,和服务器的算法是一致的
str += createPaddingString(subNu - length, replace);
}
return str;
}
private static String createPaddingString(int n, char pad) {
if (n <= 0) {
return "";
}
char[] paddingArray = new char[n];
Arrays.fill(paddingArray, pad);
return new String(paddingArray);
}
/**
* * 计算MD5校验
* * @param buffer
* * @return 空串,如果无法获得 MessageDigest实例
* */
private static String MD5(ByteBuffer buffer) {
String s = "";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(buffer);
byte tmp[] = md.digest();
// MD5 的计算结果是一个 128 位的长整数,
// 用字节表示就是 16 个字节
char str[] = new char[16 * 2];
// 每个字节用 16 进制表示的话,使用两个字符,
// 所以表示成 16 进制需要 32 个字符
int k = 0;
// 表示转换结果中对应的字符位置
for (int i = 0; i < 16; i++) {
// 从第一个字节开始,对 MD5 的每一个字节
// 转换成 16 进制字符的转换
byte byte0 = tmp[i];
// 取第 i 个字节
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
// 取字节中高 4 位的数字转换, >>>,
// 逻辑右移,将符号位一起右移
str[k++] = hexDigits[byte0 & 0xf];
// 取字节中低 4 位的数字转换
}
s = new String(str);
// 换后的结果转换为字符串
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return s;
}
}
2.实现备份类
package autoBackup;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import java.util.Scanner;
import java.util.Timer;
import java.util.TimerTask;
import md5offile.*;
public class TimerBackupFile {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
System.out.println("输入需要备份的源文件:");
String strPathSource = scan.nextLine();//输入需要备份的源目录。格式:D:\test.txt
System.out.println("输入需要备份到哪里的目标目录:");
String strPathTar = scan.nextLine();//输入需要备份到哪里的目标目录,必须存在的目录。格式:D:\javaTest\
Timer t = new Timer();
t.schedule(new BackupFile(strPathSource,strPathTar), 6000, 120000);//6秒后开始备份,每2分钟备份一次
System.out.println("当前时间:" + BackupFile.setDateFormat(System.currentTimeMillis()));
System.out.println("............");
}
}
class BackupFile extends TimerTask{
String strPathSource,strPathTar;
HashMap hm = new HashMap<>();
public BackupFile(String strPathSource,String strPathTar){
this.strPathSource = strPathSource;
this.strPathTar = strPathTar;
}
public void backupFile(String strPathSource,String strPathTar){
if(!hm.keySet().contains(BackupFile.getFileMD5(strPathSource))){//如果文件内容不变,或者恢复到之前的内容,都不备份。
hm.put(BackupFile.getFileMD5(strPathSource), setDateFormat(System.currentTimeMillis()));//把文件的MD5值存入集合hm的key中
try {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(strPathSource));
BufferedOutputStream bou = new BufferedOutputStream(
new FileOutputStream(strPathTar + randomStr(10) + new File(strPathSource).getName()));//增加随机字符串,为的是防止文件名一样,备份失败
int i = 0;
while((i = bin.read())!=-1){
bou.write(i);
}
bin.close();
bou.close();
} catch (FileNotFoundException e) {
System.out.println("文件没有找到~!");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() + "文件备份成功!");
}else{
System.out.println("文件曾经存在过,不给予备份~请注意!");
}
}
//生成随机数字符串
public String randomStr(int len){
Random rd = new Random();
String temp = "";
for(int i=0;i<=len;i++){
int num = rd.nextInt(len);
temp += String.valueOf(num);
}
return temp;
}
//转化时间格式
public static String setDateFormat(long time){
Date dt = new Date(time);
DateFormat df = new SimpleDateFormat("YYYY年MM月DD日 hh时MM分ss秒");
return df.format(dt);
}
//生成文件的MD5值
public static String getFileMD5(String strPathSource){
return MD5Util.getFileMD5(new File(strPathSource));
}
public void run(){
backupFile(strPathSource,strPathTar);
}
}
java文件备份_定时自动备份文件(java)相关推荐
- java古诗_古诗自动生成程序JAVA
[实例简介] JAVA版本的比C版本功能更加强大全面!建议大家下载使用,注意请配置WIN32环境下的java [实例截图] [核心代码] 古诗收集程序 └── CollectionVerseSyste ...
- 我的世界java路径_我的世界java路径在哪 路径有误怎么设置
我的世界的各个版本中java都是十分重要的东西,许多玩家都会遇到Java路径有误的问题,并且不知道该如何解决,其实Java的路径这个东西在每个人的电脑中都是不太一样的,一般以你安装时的位置为准,在这里 ...
- java安装_快速提示:Java中的ISO 8601持续时间
java安装 许多开发人员都知道ISO 8601定义的日期和时间的交换格式. (例如2007-08-31T16:47 +00:00代表2007年8月31日UTC的16:47 ) 但是,并不是很知名(至 ...
- aidl生成java文件_Android AIDL自动生成Java文件测试
/******************************************************************************** * Android AIDL自动生成 ...
- linux自动安装Java环境脚本,Linux 自动添加JAVA环境脚本
Linux 自动添加JAVA环境脚本 1. 删除原有的JAVA环境变量配置 ### --------------delete old config -------------------- ### ...
- 中南民族大学java考试_中南民族大学Java语言程序设计期末试卷A卷
科目序号:6002 A卷 <Java语言程序设计>期末试卷 (试卷总分:100分,考试时间:120分钟,答案写在答卷纸上) 一.判断题(每题1分,共10分) 1.无论Java源程序包含几个 ...
- java项目_好程序员Java分享从入门到服务端项目开发的过程
好程序员Java分享从入门到服务端项目开发的过程,对于打算入门或者刚刚入门学习Java的人来说,刚开始接触这门学科,往往会觉得不知所措,也会觉得很迷茫.结合前人经验,就从入门到进阶对于Java的学习而 ...
- 来电通java版_还在玩JAVA版《我的世界》?教你怎么转换存档玩光追!
简介 如果你一直在花时间扩展和开发"我的世界 (Minecraft)" Java 版世界,那下面为你公布一则好消息:此版本现可转换为"我的世界 (Minecraft)&q ...
- Java继承_这10道Java面试题!大部分的人回答不出来
1.为什么等待和通知是在 Object 类而不是 Thread 中声明的? 2.为什么Java中不支持多重继承? 3.为什么Java不支持运算符重载? 4.为什么 String 在 Java 中是不可 ...
最新文章
- 4j是合法python数字类型_python数字类型
- H264 Profile对比分析
- 多线程:AQS的一些心得
- 如何用Redlock实现分布式锁
- Java的static,final,代码块,内部类,抽象类,接口等
- linux挂接u盘视频,LINUX挂接U盘
- slf4j+logback 日志
- [单刷APUE系列]第四章——文件和目录[1]
- springboot event线程池总结
- LeetCode:35. Search Insert Position(Easy)
- UNIX高级环境编程(11)进程控制(Process Control)- 进程快照,用户标识符,进程调度...
- 计算机电源可调电阻,电脑ATX电源改0V-30V可调电源,电流7A
- 获取dns缓存/清除dns缓存
- DNS_PROBE_FINISHED_NXDOMAIN错误的解决方法
- Android原生插件开发-开发篇
- 量子力学科普书籍《见微知著》为什么值得读,看看目录就懂了
- 导弹追踪飞机c语言编程,防御导弹 (C语言代码)
- c++ 反射_实现光时域反射仪中的应用原理基于飞凌FETA40i-C核心板
- LC谐振电路跟和LC振荡电路
- 常用传感器讲解十五--触摸传感器(KY-036)
热门文章
- Programming Mobile Systems ActivitiesCase
- 怎么预防DDOS攻击?ddos云防御
- mysql 分页 去重_『备忘录』elasticsearch 去重分页查询
- 基于ADAU1701/1452 DSP有线音频调频调制信号传输设计
- 【C字符串处理】【参数传递】 一次又傻又颇有成就感的 服务器自动编译 参数传递 调试经历
- 下流社会:抖音、西虹市、延禧攻略与中产崩盘
- python爬取流浪地球_【李宁】Python大厂面试题解析+流浪地球评论抓取和分析
- 2022年上海DAMA-CDGA/CDGP数据治理认证招生简章
- 三菱FX5U系统参数配置
- 空中靶机设备优缺点分析,室内靶场专属设备