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)相关推荐

  1. java古诗_古诗自动生成程序JAVA

    [实例简介] JAVA版本的比C版本功能更加强大全面!建议大家下载使用,注意请配置WIN32环境下的java [实例截图] [核心代码] 古诗收集程序 └── CollectionVerseSyste ...

  2. 我的世界java路径_我的世界java路径在哪 路径有误怎么设置

    我的世界的各个版本中java都是十分重要的东西,许多玩家都会遇到Java路径有误的问题,并且不知道该如何解决,其实Java的路径这个东西在每个人的电脑中都是不太一样的,一般以你安装时的位置为准,在这里 ...

  3. java安装_快速提示:Java中的ISO 8601持续时间

    java安装 许多开发人员都知道ISO 8601定义的日期和时间的交换格式. (例如2007-08-31T16:47 +00:00代表2007年8月31日UTC的16:47 ) 但是,并不是很知名(至 ...

  4. aidl生成java文件_Android AIDL自动生成Java文件测试

    /******************************************************************************** * Android AIDL自动生成 ...

  5. linux自动安装Java环境脚本,Linux 自动添加JAVA环境脚本

    Linux 自动添加JAVA环境脚本 1. 删除原有的JAVA环境变量配置 ###  --------------delete old config --------------------  ### ...

  6. 中南民族大学java考试_中南民族大学Java语言程序设计期末试卷A卷

    科目序号:6002 A卷 <Java语言程序设计>期末试卷 (试卷总分:100分,考试时间:120分钟,答案写在答卷纸上) 一.判断题(每题1分,共10分) 1.无论Java源程序包含几个 ...

  7. java项目_好程序员Java分享从入门到服务端项目开发的过程

    好程序员Java分享从入门到服务端项目开发的过程,对于打算入门或者刚刚入门学习Java的人来说,刚开始接触这门学科,往往会觉得不知所措,也会觉得很迷茫.结合前人经验,就从入门到进阶对于Java的学习而 ...

  8. 来电通java版_还在玩JAVA版《我的世界》?教你怎么转换存档玩光追!

    简介 如果你一直在花时间扩展和开发"我的世界 (Minecraft)" Java 版世界,那下面为你公布一则好消息:此版本现可转换为"我的世界 (Minecraft)&q ...

  9. Java继承_这10道Java面试题!大部分的人回答不出来

    1.为什么等待和通知是在 Object 类而不是 Thread 中声明的? 2.为什么Java中不支持多重继承? 3.为什么Java不支持运算符重载? 4.为什么 String 在 Java 中是不可 ...

最新文章

  1. 4j是合法python数字类型_python数字类型
  2. H264 Profile对比分析
  3. 多线程:AQS的一些心得
  4. 如何用Redlock实现分布式锁
  5. Java的static,final,代码块,内部类,抽象类,接口等
  6. linux挂接u盘视频,LINUX挂接U盘
  7. slf4j+logback 日志
  8. [单刷APUE系列]第四章——文件和目录[1]
  9. springboot event线程池总结
  10. LeetCode:35. Search Insert Position(Easy)
  11. UNIX高级环境编程(11)进程控制(Process Control)- 进程快照,用户标识符,进程调度...
  12. 计算机电源可调电阻,电脑ATX电源改0V-30V可调电源,电流7A
  13. 获取dns缓存/清除dns缓存
  14. DNS_PROBE_FINISHED_NXDOMAIN错误的解决方法
  15. Android原生插件开发-开发篇
  16. 量子力学科普书籍《见微知著》为什么值得读,看看目录就懂了
  17. 导弹追踪飞机c语言编程,防御导弹 (C语言代码)
  18. c++ 反射_实现光时域反射仪中的应用原理基于飞凌FETA40i-C核心板
  19. LC谐振电路跟和LC振荡电路
  20. 常用传感器讲解十五--触摸传感器(KY-036)

热门文章

  1. Programming Mobile Systems ActivitiesCase
  2. 怎么预防DDOS攻击?ddos云防御
  3. mysql 分页 去重_『备忘录』elasticsearch 去重分页查询
  4. 基于ADAU1701/1452 DSP有线音频调频调制信号传输设计
  5. 【C字符串处理】【参数传递】 一次又傻又颇有成就感的 服务器自动编译 参数传递 调试经历
  6. 下流社会:抖音、西虹市、延禧攻略与中产崩盘
  7. python爬取流浪地球_【李宁】Python大厂面试题解析+流浪地球评论抓取和分析
  8. 2022年上海DAMA-CDGA/CDGP数据治理认证招生简章
  9. 三菱FX5U系统参数配置
  10. 空中靶机设备优缺点分析,室内靶场专属设备