基于Java 的增量与完全备份小工具

前段时间,因为各种原因,自己动手写了一个小的备份工具,用了一个星期,想想把它的设计思路放上来,当是笔记吧。

需求场景:这个工具起初的目的是为了解决朋友公司对其网络的限制(不可以用任何同步软件,git,外网SVN,U盘只读)。本来只是想做一个自动打包和发送邮件的工具,后来就发展成了这个。

软件功能:这个软件最终实现的功能包括1、读取配置文件,对配置文件中指定目录的文件进行日期检测,获取对应修改过的文件。2、将读出的文件进行压缩;3、将压缩文件发送到指定邮箱;4、对压缩文件进行历史版本的保留

根据最后的功能需求,工具最后选择采用的API包如下:

1、  使用commons-config实现配置文件的读写

2、  使用commons-io实现文件的检测和读写

3、  使用zip4j实现对文件的压缩

4、  使用javamail实现邮件的发送

系统最后的流程图如下:

主要的工具类如下:

  1 //用于发送邮件的Bean
  2 package com.sean.bean;
  3
  4 import java.io.File;
  5 import java.io.IOException;
  6 import java.io.InputStreamReader;
  7 import java.io.UnsupportedEncodingException;
  8 import java.util.Properties;
  9
 10 import javax.activation.DataHandler;
 11 import javax.activation.FileDataSource;
 12 import javax.mail.Address;
 13 import javax.mail.BodyPart;
 14 import javax.mail.Message;
 15 import javax.mail.Message.RecipientType;
 16 import javax.mail.MessagingException;
 17 import javax.mail.NoSuchProviderException;
 18 import javax.mail.Session;
 19 import javax.mail.Transport;
 20 import javax.mail.internet.AddressException;
 21 import javax.mail.internet.InternetAddress;
 22 import javax.mail.internet.MimeBodyPart;
 23 import javax.mail.internet.MimeMessage;
 24 import javax.mail.internet.MimeMultipart;
 25 /**
 26  * 邮件类
 27  * @author Sean
 28  * @blog http://www.cnblogs.com/Seanit/
 29  * @email [email protected]
 30  * 2015-6-9
 31  */
 32 public class EmailBean {
 33     private Session session;
 34     private MimeMessage message;
 35     private Properties properties;
 36     private MimeMultipart body;
 37
 38     /**
 39      * 默认构造函数
 40      */
 41     public EmailBean(){
 42     }
 43
 44
 45     public EmailBean(Properties properties){
 46         this.properties=properties;
 47         createMail(properties);
 48     }
 49
 50     public EmailBean(String src){
 51         this.properties=new Properties();
 52         try {
 53             properties.load(new InputStreamReader(ClassLoader.getSystemResourceAsStream(src),"utf-8"));
 54         } catch (UnsupportedEncodingException e) {
 55             // TODO Auto-generated catch block
 56             e.printStackTrace();
 57         } catch (IOException e) {
 58             // TODO Auto-generated catch block
 59             e.printStackTrace();
 60         }
 61         createMail(properties);
 62     }
 63
 64     /**
 65      * 创建连接
 66      * @author Sean
 67      * 2015-6-8
 68      * @param properties 邮箱相关配置
 69      */
 70     public  void createMail(Properties properties) {
 71         this.properties=properties;
 72         try {
 73             session=Session.getDefaultInstance(properties,null);
 74             message=new MimeMessage(session);
 75             body=new MimeMultipart();
 76         } catch (Exception e) {
 77             e.printStackTrace();
 78             throw new RuntimeException("邮件初始化失败");
 79         }
 80     }
 81
 82     /**
 83      * 设置发件人
 84      * @author Sean
 85      * 2015-6-8
 86      * @param from    发件人地址
 87      * @return        成功返回true,失败防护false
 88      */
 89     public boolean setFrom(String from){
 90         try {
 91             message.setFrom(new InternetAddress(from));
 92             return true;
 93         } catch (Exception e) {
 94             e.printStackTrace();
 95             return false;
 96         }
 97     }
 98
 99     /**
100      * 设置收件人
101      * @author Sean
102      * 2015-6-8
103      * @param toSend    收件人邮箱地址
104      * @return            成功返回true,失败防护false
105      */
106     public boolean setTOSend(String toSend){
107         try {
108             message.setRecipients(RecipientType.TO, toSend);
109             return true;
110         } catch (MessagingException e) {
111             e.printStackTrace();
112             return false;
113         }
114     }
115
116     /**
117      * 设置抄送人
118      * @author Sean
119      * 2015-6-8
120      * @param copyTo    抄送人地址
121      * @return            成功返回true,失败防护false
122      */
123     public boolean setCopyTO(String copyTo){
124         try {
125             message.setRecipients(RecipientType.CC, (Address[])InternetAddress.parse(copyTo));
126             return true;
127         } catch (Exception e) {
128             e.printStackTrace();
129             return false;
130         }
131     }
132
133
134     /**
135      * 设置主题
136      * @author Sean
137      * 2015-6-8
138      * @param subject    邮件主题
139      * @return            成功返回true,失败防护false
140      */
141     public boolean setSubject(String subject){
142         try {
143             message.setSubject(subject);
144             return true;
145         } catch (MessagingException e) {
146             e.printStackTrace();
147             return false;
148         }
149     }
150
151     /**
152      * 设置邮件正文
153      * @author Sean
154      * 2015-6-8
155      * @param content    邮件正文
156      * @return            成功返回true,失败防护false
157      */
158     public boolean setContent(String content){
159         try {
160             BodyPart bodyPart=new MimeBodyPart();
161             bodyPart.setContent(""+content, "text/html;charset=GBK");
162             body.addBodyPart(bodyPart);
163             return true;
164         } catch (Exception e) {
165             e.printStackTrace();
166             return false;
167         }
168     }
169
170     /**
171      * 添加附件
172      * @author Sean
173      * 2015-6-8
174      * @param src    附件地址
175      * @return
176      */
177     public boolean addFiles(String src){
178         try {
179             BodyPart bodyPart=new MimeBodyPart();
180             FileDataSource file =new FileDataSource(src);
181             bodyPart.setDataHandler(new DataHandler(file));
182             bodyPart.setFileName(file.getName());
183             body.addBodyPart(bodyPart);
184             return true;
185         } catch (Exception e) {
186             e.printStackTrace();
187             return false;
188         }
189     }
190
191     /**
192      * 发送邮件
193      * @author Sean
194      * 2015-6-8
195      * @return
196      */
197     public boolean send(){
198         Transport transport=null;
199         try {
200             message.setContent(body);
201             message.saveChanges();
202             transport=session.getTransport();
203             transport.connect(properties.getProperty("mail.smtp.host"), properties.getProperty("username"), properties.getProperty("password"));
204             transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
205             if(message.getRecipients(Message.RecipientType.CC)!=null){
206                 transport.sendMessage(message, message.getRecipients(Message.RecipientType.CC));
207             }
208             return true;
209         } catch (Exception e) {
210             e.printStackTrace();
211             return false;
212         }finally{
213             try {
214                 transport.close();
215             } catch (MessagingException e) {
216                 // TODO Auto-generated catch block
217                 e.printStackTrace();
218             }
219         }
220     }
221 }
 1 //用于操作配置文件的bean
 2 package com.sean.bean;
 3
 4 import org.apache.commons.configuration.ConfigurationException;
 5 import org.apache.commons.configuration.PropertiesConfiguration;
 6 /**
 7  * 配置文件操作类
 8  * 实现功能:对properties 文件进行读写操作
 9  * @author Sean
10  * 2015-6-6
11  */
12 public class PropertiesBean {
13     private String src="";
14     private PropertiesConfiguration pc=null;
15     /**
16      * 默认构造函数
17      */
18     public PropertiesBean() {}
19     public PropertiesBean(String src) {
20         this.src=src;
21         init();
22     }
23
24     /**
25      * 初始化函数
26      * @author Sean
27      * 2015-6-6
28      */
29     public void init(){
30         if(src.trim().equals("")){
31             throw new RuntimeException("The path is null");
32         }
33         try {
34             pc=new PropertiesConfiguration(src);
35         } catch (ConfigurationException e) {
36             e.printStackTrace();
37         }
38     }
39
40     /**
41      * 取值函数,根据对应的关键字获取对应的值
42      * @author Sean
43      * 2015-6-6
44      * @param key    关键字
45      * @return        返回关键字对应的值,若无该关键字,抛出异常
46      */
47     public String getValue(String key){
48         if(!pc.containsKey(key)){
49             throw new RuntimeException("not such a key");
50         }
51         return pc.getString(key);
52     }
53
54     /**
55      * 设置对应的值,传入键值对,根据关键字修改对应的值
56      * @author Sean
57      * 2015-6-6
58      * @param key    关键字
59      * @param value    值
60      */
61     public void setValue(String key,String value){
62         if(!pc.containsKey(key)){
63             throw new RuntimeException("not such a key");
64         }
65         pc.setProperty(key, value);
66         try {
67             pc.save();
68         } catch (ConfigurationException e) {
69             // TODO Auto-generated catch block
70             e.printStackTrace();
71         }
72     }
73
74     /**
75      * 设置配置文件的地址
76      * @author Sean
77      * 2015-6-6
78      * @param src    配置文件的路径
79      */
80     public void setSrc(String src) {
81         this.src = src;
82     }
83 }
//用于进行IO操作的Bean

package com.sean.bean;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
/**
 * 文件操作工具类
 * @author Sean
 * @blog http://www.cnblogs.com/Seanit/
 * @email [email protected]
 * 2015-6-6
 */
public class FilesBean {
    private List<File> list=null;
    public FilesBean(){}

    /**
     * 获取文件夹目录下的列表,目录为空返回空列表
     * @param dir 传入对应文件夹目录
     * @param ifFirst 控制递归时候的循环表示
     * @return    返回list<File>文件列表
     */
    public  List<File> listFiles(String dir,boolean ifFirst){
        /**
         * 递归判断,仅在第一次调用函数的时候新建列表,为防止重复存入列表
         */
        if(ifFirst){
            list=new ArrayList<File>();
        }

        if (dir==null||dir=="") {
            return null;
        }
        for (File f : FileUtils.getFile(dir + "\\").listFiles()) {

            if (f.isDirectory()) {
                listFiles(f.getAbsolutePath(),false);
            } else {
                list.add(f);
            }
        }
        return list;
    }

    /**
     * 根据过滤条件获取列表
     * @param dir    目录
     * @param filter    过滤条件
     * @param ifFirst    递归标识
     * @return            返回文件列表
     */
    public  List<File> listFiles(String dir,String filter,boolean ifFirst){
        /**
         * 递归判断,仅在第一次调用函数的时候新建列表,为防止重复存入列表
         */
        if(ifFirst){
            list=new ArrayList<File>();
        }

        if (dir==null||dir=="") {
            return null;
        }
        for (File f : FileUtils.getFile(dir + "\\").listFiles()) {

            if (f.isDirectory()) {
                listFiles(f.getAbsolutePath(),filter,false);
            } else {
                if(!f.getName().endsWith(filter)){
                    list.add(f);
                }

            }
        }
        return list;
    }

    /**
     * 获取指定目录下,指定日期修改后的文件
     * @param dir    传入指定检测目录
     * @param date    传入指定修改日期
      * @param ifFirst 控制递归时候的循环表示
     * @return        返回获取的文件列表,若目录或日期为空,则返回null
     */
    public  List<File> getModifiedFiles(String dir,Date date,boolean ifFirst){
        /**
         * 递归判断,仅在第一次调用函数的时候新建列表,为防止重复存入列表
         */
        if(ifFirst){
            list=new ArrayList<File>();
        }

        if (dir==null||dir==""||date==null) {
            return null;
        }

        for (File f : FileUtils.getFile(dir + "\\").listFiles()) {
            if (f.isDirectory()) {
                getModifiedFiles(f.getAbsolutePath(),date,false);
            } else {
                if (FileUtils.isFileNewer(f, date.getTime())) {
                    list.add(f);
                }
            }
        }
        return list;
    }

    /**
     * 获取某一日期之前创建的文件
     * @author Sean
     * 2015-6-9
     * @param dir    文件路径
     * @param ifFirst 控制递归时候的循环表示
     * @param date    日期
     * @return        返回列表
     */
    public  List<File> getOlderFiles(String dir,Date date,boolean ifFirst){
        /**
         * 递归判断,仅在第一次调用函数的时候新建列表,为防止重复存入列表
         */
        if(ifFirst){
            list=new ArrayList<File>();
        }

        if (dir==null||dir==""||date==null) {
            return null;
        }

        for (File f : FileUtils.getFile(dir + "\\").listFiles()) {
            if (f.isDirectory()) {
                getOlderFiles(f.getAbsolutePath(),date,false);
            } else {
                if (FileUtils.isFileOlder(f, date)) {
                    list.add(f);
                }
            }
        }
        return list;
    }

    /**
     * 获取除过滤条件外的修改文件列表
     * @param dir
     * @param date
     * @param filter
     * @param ifFirst
     * @return
     */
    public  List<File> getModifiedFiles(String dir,Date date,String filter,boolean ifFirst){
        /**
         * 递归判断,仅在第一次调用函数的时候新建列表,为防止重复存入列表
         */
        if(ifFirst){
            list=new ArrayList<File>();
        }

        if (dir==null||dir==""||date==null) {
            return null;
        }

        for (File f : FileUtils.getFile(dir + "\\").listFiles()) {
            if (f.isDirectory()) {
                getModifiedFiles(f.getAbsolutePath(),date,filter,false);
            } else {
                if (FileUtils.isFileNewer(f, date.getTime())) {
                    if(!f.getName().endsWith(filter)){
                        list.add(f);
                    }

                }
            }
        }
        return list;
    }

}
//用于压缩文件的工具类
package com.sean.utils;

import java.io.File;
import java.util.ArrayList;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;

public class ZipUtil {
    /**
     * 压缩文件列表,无目录结构
     * @author Sean
     * 2015-6-6
     * @param zipSrc zip文件地址
     * @param list    文件列表
     * @return        若成功,返回文件地址,不成功返回null
     */
    public static String zipFiles(String zipSrc,ArrayList<File> list){
        ZipParameters zipParameters=new ZipParameters();
        zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_MAXIMUM);
        ZipFile zipFile=null;
        try {
            zipFile=new ZipFile(zipSrc);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        try {
            zipFile.addFiles(list, zipParameters);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        return zipSrc;
    }

    /**
     * 压缩文件夹
     * @author Sean
     * 2015-6-6
     * @param src    文件夹地址
     * @param zipSrc 压缩文件存放地址
     * @return        若成功,返回文件夹地址,若不成功,返回null
     */
    public static String zipFolder(String src,String zipSrc){
        ZipParameters zipParameters=new ZipParameters();
        zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_MAXIMUM);
        ZipFile zipFile=null;
        try {
            zipFile=new ZipFile(zipSrc);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        try {
            zipFile.addFolder(src, zipParameters);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
        return zipSrc;
    }

    /**
     * 往zip文件中添加文件列表
     * @author Sean
     * 2015-6-7
     * @param zipSrc    zip文件路径
     * @param list        要添加的文件列表
     * @param src        要添加到zip文件中的哪个路径
     */
    public static void addFileToZip(String zipSrc,ArrayList<File> list,String src){
        ZipFile zipFile=null;
        try {
            zipFile=new ZipFile(zipSrc);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        ZipParameters zipParameters=new ZipParameters();
        zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
        zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
        zipParameters.setRootFolderInZip(src);
        try {
            zipFile.addFiles(list, zipParameters);
        } catch (ZipException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 添加文件列表到zip根目录下
     * @author Sean
     * 2015-6-7
     * @param zipSrc    zip文件地址
     * @param list        添加的文件列表
     */
    public static void addFileToZip(String zipSrc,ArrayList<File> list){
        addFileToZip(zipSrc,list,"");
    }

}
主流程:
package com.sean.main;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.sean.bean.EmailBean;
import com.sean.bean.FilesBean;
import com.sean.bean.PropertiesBean;
import com.sean.utils.ZipUtil;

/**
 * change2Mail 主程序
 * 检测文件修改情况并发送给指定邮箱
 * @version 1.0
 * @author sean
 * 2015-06-09
 *
 */
public class Change2Mail {

    /**
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException{
        //获取properties操作类
        PropertiesBean propertiesBean = new PropertiesBean("cfg.properties");
        FilesBean filesBean=new FilesBean();
        //邮件对象
        EmailBean email=new EmailBean("cfg.properties");
        String first = propertiesBean.getValue("first");
        //当前日期
        String today=new SimpleDateFormat("yyyyMMdd").format(new Date());
        //邮件正文
        String content="";
        //首次使用判断
        if (first.trim().equals("true")) {
            System.out.println("首次运行");
            content+="欢迎首次使用change2Mail,<br/>以下是你的更改文件备份目录<br/>";
            //获取检查文件目录
            String cheakDir = propertiesBean.getValue("cheakDir");
            if(!StringUtils.isEmpty(cheakDir)){
                System.out.println("正在进行更改文件目录备份。。。。。。");
                //目录分割
                String[] dirs = cheakDir.split(";");
                for (int i = 0; i < dirs.length; i++) {
                    File tmp=new File(dirs[i]);
                    List<File> list=filesBean.listFiles(dirs[i],true);
                    //创建对应文件存储目录列表
                    File file=new File(ClassLoader.getSystemResource("").getPath()+tmp.getName());
                    if(!file.exists()){
                        try {
                            file.createNewFile();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                            System.out.println("创建目录列表记录文件失败。。。。。");
                            return ;
                        }
                        }
                    //将列表写入文件
                    logFiles(file,list);
                    //压缩文件并加入邮件
                    try {
                        ZipUtil.zipFolder(dirs[i], "tmp\\"+tmp.getName()+today+".zip");
                        content+=tmp.getName()+"<br/>";
                        email.addFiles("tmp\\"+tmp.getName()+today+".zip");
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("压缩出错");
                        return ;
                    }

                }
            }
            content+="以下是你的固定备份目录<br/>";
            String zipDir = propertiesBean.getValue("zipDir");
            if(!StringUtils.isEmpty(zipDir)){
                System.out.println("正在进行固定备份目录备份。。。。。。");
                String[] zipDirs = zipDir.split(";");
                for (int i = 0; i < zipDirs.length; i++) {
                    try {
                        File tmp=new File(zipDirs[i]);
                        ZipUtil.zipFolder(zipDirs[i], "tmp\\"+tmp.getName()+today+"bak.zip");
                        content+=tmp.getName()+"<br/>";
                        email.addFiles("tmp\\"+tmp.getName()+today+"bak.zip");
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("压缩出错");
                        return ;
                    }
                }
            }
            System.out.println("更新配置文件。。。。。");
            propertiesBean.setValue("first", "false");
            propertiesBean.setValue("lastData", today);
            System.out.println("发送文件。。。。。");
            email.setFrom(propertiesBean.getValue("username"));
            email.setTOSend(propertiesBean.getValue("toSend"));
            email.setContent(content);
            email.setSubject("change2Mail备份文件"+today);
            if(email.send()){
                System.out.println("发送成功");
            }else{
                System.out.println("发送失败");
            }

        } else {
                System.out.println("备份开始。。。。。");
                String data=propertiesBean.getValue("lastData");
                String filter=propertiesBean.getValue("filter");
                String cheakDir = propertiesBean.getValue("cheakDir");
                content+="你好,自"+data+"起的文件变动如下:<br/>";
                if(!StringUtils.isEmpty(cheakDir)){
                    System.out.println("正在进行更改文件目录备份。。。。。。");
                    String[] dirs = cheakDir.split(";");
                    for (int i = 0; i < dirs.length; i++) {
                        File tmp=new File(dirs[i]);
                        File file=new File(ClassLoader.getSystemResource("").getPath()+tmp.getName());
                        if(!file.exists()){
                            try {
                                file.createNewFile();
                            } catch (IOException e) {
                                System.out.println("创建文档失败");
                                e.printStackTrace();
                            }
                        }
                        content+="文件夹"+tmp.getName()+":<br/>";
                        List<File> list=filesBean.getModifiedFiles(dirs[i],new SimpleDateFormat("yyyyMMdd").parse(data),filter,true);
                        List<File> now =filesBean.listFiles(dirs[i],filter,true);
                        List<File> news=new ArrayList<File>();
                        List<File> del=new ArrayList<File>();
                        List<File> modefy=new ArrayList<File>();
                        List<String> lines=null;
                        try {
                            lines=FileUtils.readLines(file);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        System.out.println("检查新建和修改的文件。。。。。。");
                        for(File f:list){
                            if(!lines.contains(f.getAbsolutePath())){
                                news.add(f);
                            }else{
                                modefy.add(f);
                            }
                        }

                        System.out.println("检查删除的文件。。。。。。");
                        for(String f:lines){
                            File old=new File(f);
                            if(!now.contains(old)){
                                del.add(old);
                            }
                        }
                        logFiles(file,now);
                        content+="删除文件:<br/>";
                        for(File f:del){
                            content+="	"+f.getName()+"<br/>";
                        }
                        content+="新增文件:<br/>";
                        for(File f:news){
                            content+="	"+f.getName()+"<br/>";
                        }
                        content+="修改文件:<br/>";
                        for(File f:modefy){
                            content+="	"+f.getName()+"<br/>";
                        }
                        try {
                            if(list.size()!=0){
                                list.add(file);
                                ZipUtil.zipFiles("tmp\\"+tmp.getName()+today+".zip", (ArrayList<File>)list);

                                email.addFiles("tmp\\"+tmp.getName()+today+".zip");
                            }

                        } catch (Exception e) {
                            e.printStackTrace();
                            System.out.println("压缩失败");
                            return;
                        }

                    }

                    String zipDir = propertiesBean.getValue("zipDir");
                    if(!StringUtils.isEmpty(zipDir)){
                        System.out.println("正在进行固定备份目录备份。。。。。。");
                        String[] zipDirs = zipDir.split(";");
                        for (int i = 0; i < zipDirs.length; i++) {
                            try {
                                File tmp=new File(zipDirs[i]);
                                ZipUtil.zipFolder(zipDirs[i], "tmp\\"+tmp.getName()+today+"bak.zip");
                                email.addFiles("tmp\\"+tmp.getName()+today+"bak.zip");
                            } catch (Exception e) {
                                e.printStackTrace();
                                System.out.println("压缩出错");
                                return ;
                            }
                        }
                    }

                    System.out.println("更改配置文件。。。。。");
                    propertiesBean.setValue("lastData", today);
                    System.out.println("发送文件。。。。。");
                    email.setFrom(propertiesBean.getValue("username"));
                    email.setTOSend(propertiesBean.getValue("toSend"));
                    email.setContent(content);
                    email.setSubject("change2Mail备份文件"+today);
                    if(email.send()){
                        System.out.println("发送成功");
                    }else{
                        System.out.println("发送失败");
                    }

                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
                     long to = df.parse(today).getTime();
                     long todel=Integer.parseInt(propertiesBean.getValue("time"))*(1000 * 60 * 60 * 24);
                     Date lastBak=new Date(to-todel) ;
                     System.out.println("删除"+df.format(lastBak)+"之前保存的历史文件。。。。。");
                     List<File> fileToDel=filesBean.getOlderFiles("tmp\\", lastBak,true);
                     for(File f:fileToDel){
                         try {
                             FileUtils.deleteQuietly(f);
                        } catch (Exception e) {
                            // TODO: handle exception
                            e.printStackTrace();
                            System.out.println("删除"+f.getName()+"文件失败");
                        }

                     }
                    System.out.println(new Date());
                }
        }
    }
    /**
     * 将文件列表的绝对地址输出到一个文件中
     * @param file    输出文件
     * @param list    文件列表
     * @return        成功返回true,失败返回false
     */
    public static boolean logFiles(File file, List<File> list) {
        List<String> lines=new ArrayList<String>();
        try {
                for (File f : list) {
                    lines.add(f.getAbsolutePath());
                }
                FileUtils.writeLines(file, lines,false);
                return true;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
    }

}
配置文件:
#autho:sean
#data:2015/05/26
#email:[email protected]126.com

#mail config  javamail的配置
mail.debug = true
mail.smtp.auth = true
mail.smtp.host = smtp.126.com
mail.transport.protocol = smtp

#mail info 邮箱设置
username = [email protected].com
password = 121212
toSend = 121212@qq.com

#soft config 软件设置
#if the fisrt time to run  是否第一次运行
first = true
#the path to check 检测的目录
cheakDir = F:\\myfolder\\BaseClass;
#the path allways to zip    完全备份的目录
zipDir = F:\\myfolder\\myProject\\Change2Mail;
#the data lastcheck 最后备份时间
lastData = 20150629
#storage life of the bak zip 保留文件
time = 5
#filter string    过滤条件
filter = .class

工具github地址:https://github.com/Seanid/change2mail

为了便于使用,工具最后导出为jar包,并编写了一个bat进行执行,加入了jre文件夹,可以再无jdk环境下使用。最后压缩包地址:http://pan.baidu.com/s/1i3vQJv3

本工具只是个人闲时开发,纯属娱乐,大神勿喷

时间: 2024-10-08 14:19:08

基于Java 的增量与完全备份小工具的相关文章

基于Java NIO的多人在线聊天工具源码实现(登录,单聊,群聊)

近来在学习Java NIO网络开发知识,写了一个基于Java NIO的多人在线聊天工具练练手.源码公开在Coding上: https://coding.net/u/hust_wsh/p/MyChat/git ,开发环境是Ubuntu14.04+Eclipse Mars+JDK1.8. 要想编写一个基于Java NIO的多人在线聊天工具,我总结需要以下几方面的地址:客户端服务器模型,Java NIO中的Selector,SocketChannel,ByteBuffer,Collections以及序

博客备份小工具3

[转]博客备份小工具3 接着 博客转发小工具2 ,又弄了一个第三版.主要功能有:博客备份到本地.浏览备份到本地的博客.关键字搜索本地的博客和转发博客可以选择个人分类 填写Tag标签.其实想了想,转发博客干嘛非要在本地客户端转发,直接在博客园的页面用js不就可以达到目的么.想是这么想,还没尝试.等我写完了这个博客就去试试..继续回到这个小工具,说实在的本人做的这个小工具界面丑的那是..反正就是很丑很丑啦.没办法,没有美工的那种艺术细胞.还有就是,整个功能其实真没什么技术含量,还是html的抓取,w

Java正则表达式——测试正则表达式的一个小工具

正则表达式是一种强大而灵活的文本处理工具.使用它我们能以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索.一旦找到了匹配这些模式的部分,你就能够随心所欲地对它们进行处理. 关于正则表达式的语法,网上对此有介绍的文章实在是多不胜数,实在找不到,还可以查看Java的API文档,就不多介绍了.这里主要介绍一个可以测试正则表达式的小工具.直接上代码: 1 package com.test.stringregex; 2 //{Args: abcabcabcdefabc "abc+" &q

配置文件和配置表定期备份小工具

现在维护的配置文件/表都是人手工备份,上次某机器宕机,想在别的机器上拉起应用,去找备份的时候,发现最近的备份还是去年的,因此有了这个想法写这么一个小工具才进行定期备份.其实细极思恐,每天备份一下还是很有必要的,出事了,也能找到是哪天开始的不是? 设计的思路还是先把哪些机器的文件.哪个数据库的表需要备份,放入数据库中,然后弄一个shell,在某个机器上启动这个shell,使用ftp去备份配置文件,使用exp去dmp数据库文件,完成备份. 首先是数据库设计部分,需要两张表: "机器表":

【开源一个小工具】一键将网页内容推送到Kindle

最近工作上稍微闲点,这一周利用下班时间写了一个小工具,其实功能挺简单但也小折腾了会. 工具名称:Simple Send to Kindle Github地址:https://github.com/zhanjindong/SimpleSendToKindle 功能:Windows下一个简单的将网页内容推送到Kindle的工具. 写这个工具的是满足自己的需求.自从买了Kindle paperwhite 2,它就成了我使用率最高的一个电子设备.相信很多Kindle拥有者和我一样都有这样一个需求:就是白

HUDSON(Java开发的一种持续集成工具)

Hudson是Jenkins的前身,是基于Java开发的一种持续集成工具,用于监控程序重复的工作,包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. Hudson的特性 1.易于安装-只要把hudson.war部署到servlet容器,不需要数据库支持. 2.易于配置-所有配置都是通过其提供的web界面实现. 3.集成RSS/E-mail/IM-通过RSS发布构建结果或当构建失败时通过e-mail实时通知. 4.生成JUnit/TestNG测试报告. 5.分布式构建支持-H

Java学习----Jenkins(善假于工具)

最近开始开发java项目,对于java这一套程序的发布流程进行了梳理,主要用到工具就是Jenkins,那么什么是Jenkins呢?问题就出来了. 提到Jenkins,就不得不提到其所属的范围或者说是本质,Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作. 我们知道在信息现代化的今天,工具的使得大大的提高了我们开发和工作的效率,比如svn使得我们更好地实现了组内的代码共享,axure使得团队的合作

基于binlog的增量备份

1.1 增量备份简介 增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份与前一次相比增加或者被修改的文件.这就意味着,第一次增量备份的对象是进行全备后所产生的增加和修改的文件:第二次增量备份的对象是进行第一次增量备份后所产生的增加和修改的文件,如此类推.这种备份方式最显著的优点就是:没有重复的备份数据,因此备份的数据量不大,备份所需的时间很短.但增量备份的数据恢复是比较麻烦的.您必须具有上一次全备份和所有增量备份磁带(一旦丢失或损坏其中的一个增量,就会造成恢复的失败),并且它们必

【安卓】数据库基于脚本的&quot;增量更新&quot;,每次更新时不需修改java代码、!

思路: 1.当然是基于SQLiteOpenHelper.onCreate(第一次安装程序时调用).onUpdate(升级程序时调用) 2.用"脚本"(脚本制作具体方法问度娘)做数据库升级,文件名标识对应版本,java中根据"上一版本.当前版本"选择执行的脚本. 升级时,修改DB_VERSION(当前版本)即可. DBManager.java: package com.example.test; import java.io.ByteArrayOutputStream