很早我就知道這個需求,本來想抄捷徑使用cron table去定時執行tar指令,將Log檔壓縮備份再刪Log檔。但想想,還是寫的工具程式好了,以下飯粒抄自O'Reilly的Java IO一書。
private void copy(InputStream in, OutputStream out) throws IOException { // Stream Copy
synchronized (in) {
synchronized (out) {
byte[] buffer = new byte[1024];
while (true) {
int bytesRead = in.read(buffer);
if (bytesRead == -1) break;
out.write(buffer, 0, bytesRead);
}
}
}
} // 2010/2/15補述,Apache的commons-io提供了CopyUtils.copy(in, out)可取代這個method
public void doZip(String outputFile, File[] files) throws Exception { // 將Files全壓縮到outputFile
FileOutputStream fout = new FileOutputStream(outputFile);
ZipOutputStream zout = new ZipOutputStream(fout);
zout.setLevel(Deflater.BEST_COMPRESSION);
for (int i=0; i<files.length; i++) {
ZipEntry ze = new ZipEntry(files[i].getName());
try {
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(ze);
this.copy(fin, zout);
zout.closeEntry();
fin.close();
files[i].deleteOnExit();
} catch (IOException e) {
this.logger.warn("doZip", e);
}
}
zout.close();
}
第二個需求來了,備份超過限定日期所有Log檔,關鍵在取得File[]所設定的Filter。我就在Java String上的Regex吃了暗虧,原來功能並沒Perl齊全。比如:"com.xyz.2009-05-12".matches("\\d{4}(\\-\\d\\d){2}$");。目的是比對到後綴為yyyy-mm-dd的格式。結果我才知道String的matches,不能只符合部份字串,如上例的com.xyz.沒符合到就算false,所以要全部符合才會return true,是故更正後的pattern是:com.xyz.2009-05-12".matches(".+\\d{4}(\\-\\d\\d){2}$");,加個.+將com.xyz.全部match進來。