java、golang記錄檔轉儲壓縮實現

來源:互聯網
上載者:User

日誌的轉儲和壓縮是非常關鍵的,它不僅可以減少硬碟空間佔用,主要還可以在發生故障時根據日誌定位出故障原因。下面來看看golang和java的檔案轉儲實現。

go語言:

用到了filepath包下的Walk方法,具體說明可以參看曆史文章:
go語言path/filepath包之Walk源碼解析

package mainimport ( "fmt" "os" "io" "archive/zip" "path/filepath" "time" "log")func main() { logFile := "D:/tmp/successLog/logs/root.log" backFile := "D:/tmp/successLog/logs/root_" + time.Now().Format("20060102150405") + ".zip"  err := zipFile(logFile, backFile) if err != nil {   log.Println(fmt.Sprintf("zip file %s to %s error : %v", logFile, backFile, err))   return } else {   os.Remove(logFile) } //轉儲後建立新檔案 //createFile() //修改檔案許可權 //os.Chmod(backfile, 0400) //刪除備份檔案 //deleteOldBackfiles(dir)}func zipFile(source, target string) error { zipFile, err := os.OpenFile(target, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0440) if err != nil {   log.Println(err)   return err } defer zipFile.Close() archive := zip.NewWriter(zipFile) defer archive.Close() return filepath.Walk(source, func(path string, info os.FileInfo, err error) error {   if err != nil {     return err   }   header, err := zip.FileInfoHeader(info)   if err != nil {     return err   }   if !info.IsDir() {     header.Method = zip.Deflate   }   header.SetModTime(time.Now().UTC())   header.Name = path   writer, err := archive.CreateHeader(header)   if err != nil {     return err   }   if info.IsDir() {     return nil   }   file, err := os.Open(path)   if err != nil {     return err   }   defer file.Close()   _, err = io.Copy(writer, file)   return err })}
go壓縮結果

java版:

說明見注釋。

import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.zip.CRC32;import java.util.zip.CheckedOutputStream;import java.util.zip.ZipEntry;import java.util.zip.ZipOutputStream;/*** @program: website* @description: 轉儲壓縮檔* @author: smallsoup* @create: 2018-08-12 17:58**/public class ZipFile {   private static final Logger LOGGER = LoggerFactory.getLogger(ZipFile.class);   /**    * 格式檔案名格式    */   private static final String AUDIT_LOG_FORMAT = "yyyyMMddHHmmssSSS";   /**    * 壓縮後檔案尾碼    */   private static final String AUDIT_FILE_ZIP_SUFFIX = ".zip";   /**    * 壓縮前檔案尾碼    */   private static final String AUDIT_FILE_EXT = ".log";   private static final int ZIP_BUFFER = 4096;   /**    * 控制壓縮後的檔案解壓後是否帶base路徑    */   private static final String rootPath = "";   public static void main(String[] args) throws IOException {       System.out.println();       new ZipFile().zipAuditLogFile("D:/tmp/successLog/logs/root.log");   }   /**    * 日誌壓縮    *    * @param waitZipFile 要壓縮檔名    * @throws IOException    */   private void zipAuditLogFile(String waitZipFile) throws IOException {       File oldFile = new File(waitZipFile);       if (!oldFile.exists()) {           LOGGER.error("zipAuditLogFile name is {} not exist", waitZipFile);           return;       }       //產生zip檔案名稱       DateFormat dataFormat = new SimpleDateFormat(AUDIT_LOG_FORMAT);       String formatTime = dataFormat.format(oldFile.lastModified());       int end = waitZipFile.length() - AUDIT_FILE_EXT.length();       String zipFileName = waitZipFile.subSequence(0, end) + "_" + formatTime + AUDIT_FILE_ZIP_SUFFIX;       File zipFile = new File(zipFileName);       FileOutputStream zipfos = null;       ZipOutputStream zipOs = null;       CheckedOutputStream cos = null;       try {           zipfos = new FileOutputStream(zipFile);           cos = new CheckedOutputStream(zipfos, new CRC32());           zipOs = new ZipOutputStream(cos);           compress(oldFile, zipOs, rootPath);           if (zipFile.exists()) {               // 寫完的記錄檔許可權改為400               try {                   //linux上才可以運行,windows上需要裝cygwin並且把cygwin的bin目錄加到環境變數的path中才可以                   Runtime.getRuntime().exec("chmod 400 -R " + zipFile);                   //壓縮後刪除舊檔案                   boolean isDelete = oldFile.delete();                   //建立新檔案                   if (isDelete) {                       oldFile.createNewFile();                   }//                    boolean isSuccess = PathUtil.setFilePermision(zipFile.toPath(), ARCHIVE_LOGFILE_PERMISION);//                    LOGGER.warn("set archive file: {}, permision result is {}", zipFile.getAbsolutePath(), isSuccess);               } catch (IOException e) {                   LOGGER.error("set archive file:{} permision catch an error: {}", zipFile, e);               }           }       } finally {           if (null != zipOs) {               zipOs.close();           }           if (null != cos) {               cos.close();           }           if (null != zipfos) {               zipfos.close();           }       }   }   /**    * 壓縮檔或目錄    *    * @param oldFile 要壓縮的檔案    * @param zipOut  壓縮檔流    * @param baseDir baseDir    * @throws IOException    */   private void compress(File oldFile, ZipOutputStream zipOut, String baseDir) throws IOException {       if (oldFile.isDirectory()) {           compressDirectory(oldFile, zipOut, baseDir);       } else {           compressFile(oldFile, zipOut, baseDir);       }   }   /**    * 壓縮目錄    *    * @param dir     要壓縮的目錄    * @param zipOut  壓縮檔流    * @param baseDir baseDir    * @throws IOException    */   private void compressDirectory(File dir, ZipOutputStream zipOut, String baseDir) throws IOException {       File[] files = dir.listFiles();       for (File file : files) {           compress(file, zipOut, baseDir + dir.getName() + File.separator);       }   }   /**    * 壓縮檔    *    * @param oldFile 要壓縮的檔案    * @param zipOut  壓縮檔流    * @param baseDir baseDir    * @throws IOException    */   private void compressFile(File oldFile, ZipOutputStream zipOut, String baseDir) throws IOException {       if (!oldFile.exists()) {           LOGGER.error("zipAuditLogFile name is {} not exist", oldFile);           return;       }       BufferedInputStream bis = null;       try {           bis = new BufferedInputStream(new FileInputStream(oldFile));           ZipEntry zipEntry = new ZipEntry(baseDir + oldFile.getName());           zipOut.putNextEntry(zipEntry);           int count;           byte data[] = new byte[ZIP_BUFFER];           while ((count = bis.read(data, 0, ZIP_BUFFER)) != -1) {               zipOut.write(data, 0, count);           }       } finally {           if (null != bis) {               bis.close();           }       }   }}  
java壓縮結果

修改許可權也可以利用Java7中NIO.2對中繼資料檔案操作的支援,具體可以查看NIO包的使用,其相關教程見文末說明。

代碼如下:

package com.website.common;import java.io.IOException;import java.nio.file.FileSystems;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.attribute.PosixFilePermission;import java.nio.file.attribute.PosixFilePermissions;import java.util.Set;/*** 提供檔案路徑公用函數 改變許可權,判斷是否正規檔案,判斷是否路徑在安全路徑下等** @program: website* @description: 路徑工具, 修改許可權* @author: smallsoup* @create: 2018-08-14 07:56**/public class PathUtil {   /**    * POSIX表示可移植作業系統介面,並不局限於unix類系統    */   private static final boolean ISPOSIX = FileSystems.getDefault().supportedFileAttributeViews().contains("posix");   /**    * 數字許可權格式,如600    */   private static final int PERM_LEN_THREE = 3;   /**    * 如765   rwxrw_r_x    */   private static final int PERM_LEN_NINE = 9;   /**    * 設定檔案的許可權,盡在posix下有效    *    * @param file 檔案    * @param perm 許可權 類似 “rw-r-----”, "640"    * @return true 修改成功 false 修改失敗    * @throws IOException    */   public static boolean setFilePermision(Path file, String perm) throws IOException {       if (!ISPOSIX) {           return true;       }       // 750 -> "rwxr-x---"       if (perm.length() == PERM_LEN_THREE) {           perm = trans2StrPerm(perm);       }       if (perm.length() != PERM_LEN_NINE) {           return false;       }       Set<PosixFilePermission> perms = PosixFilePermissions.fromString(perm);       Files.setPosixFilePermissions(file, perms);       return true;   }   /**    * 轉換    *    * @param digitPerm 長度為3的數字字串    * @return    */   private static String trans2StrPerm(String digitPerm) {       StringBuilder builder = new StringBuilder(9);       // owner       builder.append(toStringPerm(digitPerm.charAt(0)));       // group       builder.append(toStringPerm(digitPerm.charAt(1)));       // other       builder.append(toStringPerm(digitPerm.charAt(2)));       return builder.toString();   }   private static String toStringPerm(char ch) {       switch (ch - '0') {           case 7:               return "rwx";           case 6:               return "rw-";           case 5:               return "r-x";           case 4:               return "r--";           case 3:               return "-wx";           case 2:               return "-w-";           case 1:               return "--x";           case 0:               return "---";           default:               return "";       }   }}

go語言、NIO等學習資料 可以關注文末公眾號後在後台回複【1】 擷取。

最後,csdn資源,收集了海量學習資料,如果你準備入IT坑,勵志成為優秀的程式猿,那麼這些資源很適合你,包括java、go、python、springcloud、elk、嵌入式 、大資料、面試資料、前端等資源。同時我們組建了一個技術交流群,裡面有很多大佬,會不定時分享技術文章,如果你想來一起學習提高,可以關注以下公眾號後回複【2】,擷取。

我是小碗湯,我們一起學習,掃碼關注,精彩內容第一時間推給你

歡迎掃碼關注
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.