前些天写了个小练习,定期备份web工程,感觉有点意思,也有点小用处。由于最近封闭开发,下班比较晚,所以电脑一般不关机,省得麻烦,这样就可以一直开着我本机的web服务器,每天备份我的web工程了。备份可是个好东西,搞不好哪天程序出了点小问题,或者电脑出了点小故障,再或者一不小心按了个delete,备份可就大有用处了。
我最终要实现的功能是每天晚上 23:59:59 的时候将我的web工程压缩成一个以日期为后缀的 .zip 文件。
首先是写一个压缩 zip 文件的类,可以将一个或多个文件(或文件夹)压缩成zip文件。利用很多web容器都提供的ant.jar,可以很方便的压缩一个zip文件。网上有很多压缩zip的例子,不过有的例子压缩出的zip中,生成了一些多余的东西,下面是我的压缩zip文件的类:
- package com.why.bak;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import org.apache.tools.zip.ZipOutputStream;
- /**
- * 将一个或多个文件压缩成 .zip 格式
- * @author 吴宏宇 2009-2-27
- *
- */
- public class ZipUtil {
- /**
- * 传入要压缩成的文件名,待压缩文件名或目录名,将待压缩文件或目录压缩成 .zip格式
- * 如 要将 C 盘下 test 文件夹压缩成 test_bak.zip 文件,则执行
- * zip("C:\\test_bak.zip","C:\\testzip");
- * @param zipFileName 压缩后的文件名(包含全路径名)
- * @param inputFileName 待压缩文件名(包含全路径名)
- * @throws Exception
- */
- public void zip(String zipFileName, String inputFileName) throws Exception {
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream( zipFileName));
- zip(out, new File(inputFileName), new File(inputFileName).getName());
- // System.out.println("zip done");
- out.close();
- }
- /**
- * 传入要压缩成的文件名,待压缩文件名或目录名数组,将待压缩的多个文件或目录压缩成 .zip格式
- * 如 要将 C 盘下 test 文件夹及 test.txt 文件压缩成 test_bak.zip 文件,则执行
- * zip("C:\\test_bak.zip",new String[]{"C:\\test.txt", "C:\\test"});
- * @param zipFileName
- * @param inputFileName
- * @throws Exception
- */
- public static void zips(String zipFileName, String inputFileName[]) throws Exception {
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream( zipFileName));
- File file ;
- for(int i=0;i<inputFileName.length;i++){
- file = new File(inputFileName[i]);
- zip(out, file, file.getName());
- }
- // System.out.println("zip done");
- out.close();
- }
- public static void zip(ZipOutputStream out, File f, String base)
- throws Exception {
- if (f.isDirectory()) {
- File[] fl = f.listFiles();
- String symbol = "";
- if (System.getProperty("os.name").startsWith("Windows")) {
- symbol = "\\";
- } else {
- symbol = "/";
- }
- for (int i = 0; i < fl.length; i++) {
- zip(out, fl[i], base + symbol + fl[i].getName());
- }
- } else {
- out.putNextEntry(new org.apache.tools.zip.ZipEntry(base));
- FileInputStream in = new FileInputStream(f);
- int b;
- //System.out.println(base);
- while ((b = in.read()) != -1) {
- out.write(b);
- }
- in.close();
- }
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- String files[] = {"C:\\response.txt", "C:\\testzip测试","C:\\cmd.txt"};
- try {
- zips("C:\\test测试zips.zip", files);zips("",new String[]{"C:\\response.txt", "C:\\testzip测试","C:\\cmd.txt"});
- } catch (Exception e) {
- // TODO 自动生成 catch 块
- e.printStackTrace();
- }
- }
- }
package com.why.bak;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.tools.zip.ZipOutputStream;
/**
* 将一个或多个文件压缩成 .zip 格式
* @author 吴宏宇 2009-2-27
*
*/
public class ZipUtil {
/**
* 传入要压缩成的文件名,待压缩文件名或目录名,将待压缩文件或目录压缩成 .zip格式
* 如 要将 C 盘下 test 文件夹压缩成 test_bak.zip 文件,则执行
* zip("C:\\test_bak.zip","C:\\testzip");
* @param zipFileName 压缩后的文件名(包含全路径名)
* @param inputFileName 待压缩文件名(包含全路径名)
* @throws Exception
*/
public void zip(String zipFileName, String inputFileName) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream( zipFileName));
zip(out, new File(inputFileName), new File(inputFileName).getName());
// System.out.println("zip done");
out.close();
}
/**
* 传入要压缩成的文件名,待压缩文件名或目录名数组,将待压缩的多个文件或目录压缩成 .zip格式
* 如 要将 C 盘下 test 文件夹及 test.txt 文件压缩成 test_bak.zip 文件,则执行
* zip("C:\\test_bak.zip",new String[]{"C:\\test.txt", "C:\\test"});
* @param zipFileName
* @param inputFileName
* @throws Exception
*/
public static void zips(String zipFileName, String inputFileName[]) throws Exception {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream( zipFileName));
File file ;
for(int i=0;i<inputFileName.length;i++){
file = new File(inputFileName[i]);
zip(out, file, file.getName());
}
// System.out.println("zip done");
out.close();
}
public static void zip(ZipOutputStream out, File f, String base)
throws Exception {
if (f.isDirectory()) {
File[] fl = f.listFiles();
String symbol = "";
if (System.getProperty("os.name").startsWith("Windows")) {
symbol = "\\";
} else {
symbol = "/";
}
for (int i = 0; i < fl.length; i++) {
zip(out, fl[i], base + symbol + fl[i].getName());
}
} else {
out.putNextEntry(new org.apache.tools.zip.ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
//System.out.println(base);
while ((b = in.read()) != -1) {
out.write(b);
}
in.close();
}
}
/**
* @param args
*/
public static void main(String[] args) {
String files[] = {"C:\\response.txt", "C:\\testzip测试","C:\\cmd.txt"};
try {
zips("C:\\test测试zips.zip", files);zips("",new String[]{"C:\\response.txt", "C:\\testzip测试","C:\\cmd.txt"});
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
第二步,实现在 web 工程启动后定期执行备份任务。
java.util.Timer 这个类有定时执行计划任务的功能,通过设定定时器的间隔时间,自动在此间隔时间后执行预先安排好的任务。
通过 timer.schedule(TimerTask,0,0)方法设置要执行的任务以及间隔时间。schedule方法的第一个参数是需要执行的任务,类型为java.util.TimerTask,第二个参数为执行任务前等待时间,若为0则表示不等待,第三个参数为间隔时间,单位为毫秒。
当web工程启动时,定时器开始计时,在整个web工程的生命周期里,会定期执行备份的任务,此处用Servlet的监听器类来启动定时器,通过在配置文件里配置此监听器, 让其在工程启动时自动加载运行,存活期为整个Web工程生命期。
- package com.why.bak;
- import java.text.ParseException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Timer;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- public class BakListener implements ServletContextListener {
- private Timer timer = null;
- /**
- * 在Web应用结束时停止任务
- */
- public void contextDestroyed(ServletContextEvent arg0) {
- timer.cancel(); // 定时器销毁
- }
- /**
- * 在Web应用启动时初始化任务
- */
- public void contextInitialized(ServletContextEvent arg0) {
- Date date = new Date(); //取得当前时间,精确到天
- Date toNight ;
- SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
- SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- try {
- toNight = formatter2.parse(formatter1.format(date)+" 23:59:59");
- System.out.println("toNight = "+formatter2.format(toNight));
- timer = new Timer(true);
- //设置任务计划,启动和间隔时间
- timer.schedule(new BakTask(), toNight, 86400000);//设置当前日期的23:59:59 开始执行 86400000毫秒为一天
- } catch (ParseException e) {
- e.printStackTrace();
- System.out.println("备份监听未能成功启动");
- }
- }
- }
package com.why.bak;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class BakListener implements ServletContextListener {
private Timer timer = null;
/**
* 在Web应用结束时停止任务
*/
public void contextDestroyed(ServletContextEvent arg0) {
timer.cancel(); // 定时器销毁
}
/**
* 在Web应用启动时初始化任务
*/
public void contextInitialized(ServletContextEvent arg0) {
Date date = new Date(); //取得当前时间,精确到天
Date toNight ;
SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
toNight = formatter2.parse(formatter1.format(date)+" 23:59:59");
System.out.println("toNight = "+formatter2.format(toNight));
timer = new Timer(true);
//设置任务计划,启动和间隔时间
timer.schedule(new BakTask(), toNight, 86400000);//设置当前日期的23:59:59 开始执行 86400000毫秒为一天
} catch (ParseException e) {
e.printStackTrace();
System.out.println("备份监听未能成功启动");
}
}
}
要使用这个监听器需要在 web.xml 中配置如下内容:
- <listener>
- <listener-class>com.why.bak.BakListener</listener-class>
- </listener>
<listener> <listener-class>com.why.bak.BakListener</listener-class> </listener>
第三步,实现执行备份任务的类。
实现备份任务的类需继承 java.util.TimerTask ,在这个类中实现备份工程文件的功能。这里将要备份的文件名以及要生成的文件名写死在了程序里,其实可以写在配置文件中,通过读取配置文件制定要备份的内容。
- package com.why.bak;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.TimerTask;
- public class BakTask extends TimerTask {
- public void run() {
- ZipUtil zipUtil = new ZipUtil();
- String fileToBak = "E:\\obs_workspace\\OBSWeb_wuhy"; //要备份的文件名
- String newFileName = "E:\\obs_workspace\\OBSWeb_why_bak\\OBSWeb_wuhy-bak-"; //要生成的.zip文件名
- Date date = new Date(); //取得当前时间
- SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
- try {
- newFileName = newFileName + formatter.format(date) +".zip";
- System.out.println("newFileName = " + newFileName);
- zipUtil.zip(newFileName, fileToBak);
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("备份出现异常");
- }
- }
- }