這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
工作中用go語言寫了點指令碼代替python的功能,涉及檔案讀寫,記錄如下
package mainimport ( "os" "os/exec" "log" "bytes" "strings" "bufio" //檔案讀寫 "strconv"// "fmt")const pwd = "/usr/local/nginx/htdocs/"func get_logname(ziplog_name string) (string) { var out bytes.Buffer //hint:用exec.Command擷取一個Cmd對象,設定標準輸出到out,執行Run操作 cmd := exec.Command("unzip","-o",ziplog_name,"-d",ziplog_name[0:len(ziplog_name)-4]) cmd.Stdout = &out err := cmd.Run() if err != nil { log.Fatal(err) } //hint:標準輸出可通過out.String()擷取,用strings.Index擷取指定字串所在位置 i:=strings.Index(out.String(),"inflating: ") log_name:=out.String()[i+len("inflating: "):] //hint:通過strings.Trim刪除字串兩側的分行符號以及空格 log_name = strings.Trim(log_name,"\n ") return log_name}func getinfo(line string)(string,string,string) { appname, day, curhour := "", "", "" //用strings的庫函數拆分字串,可以用&&添加多個判斷 if info := strings.Split(line, " "); len(info) > 5 && info[3] == "OK" { appname = info[4] } if tday := strings.Split(line, "["); len(tday) > 1 { tday = strings.Split(tday[1]," ") day = ... } if hour := strings.Split(line, ":"); len(hour) > 1 { //hint 用strconv庫函數判斷字串是否為數字 _, err := strconv.Atoi(hour[1]) if err != nil { return "","","" } curhour = hour[1] } return appname, day, curhour}func saveline(filepath, filename, line string) { //開啟檔案,如果失敗,建立檔案夾先,開啟檔案為append,和讀寫 f, err := os.OpenFile(filename, os.O_APPEND|os.O_RDWR, 0666) if err != nil { //如果檔案夾已經建立,返回nil,MkdirAll是遞迴建立子目錄 err = os.MkdirAll(filepath, 0755) if err != nil { log.Fatal(err) } f, err = os.OpenFile(filename, os.O_APPEND|os.O_RDWR, 0666) if err != nil { //如果檔案不存在,則用Create建立,預設開啟類型為讀寫 f, err = os.Create(filename) if err != nil { log.Fatal(err) } } } //設定defer關閉檔案 defer f.Close() //hint:用bufio逐行寫入檔案 line = line + "\n" b := bufio.NewWriter(f) if n, err := b.WriteString(line); err != nil || n != len(line) { log.Fatal(err) } //hint:調用Flush將記憶體寫到磁碟 if err = b.Flush(); err != nil { log.Fatal(err) }}func worker(line, p1, p2 string) { app, day, hour := getinfo(line) var filepath, filename string if day == "" || hour == "" { return } if app != "" { filepath = pwd + "workdir/app/" + app + "/" + day + "/" filename = filepath + hour + ".log" saveline(filepath, filename, line) } filepath = pwd + "workdir/backup/" + day + "/" + log_from + "/" filename = filepath + hour + ".log" saveline(filepath, filename, line)}func main() { //hint :os.Args擷取命令列參數,用len擷取參數個數 if len(os.Args) < 3 { log.Panic("fatal error") } para1, para2 := os.Args[1], os.Args[2] //hint :調用os的函數Chdir實現目錄切換 if err := os.Chdir(pwd + "workdir/"); err != nil { log.Panic("fatal error") } //hint :設定defer,函數退出時調用os.RemoveAll,遞迴刪除子目錄以及檔案 defer os.RemoveAll("dir") defer f.Close() //hint :用os.Open開啟檔案以及bufio逐行讀取 f, err := os.Open("file.exist") if err != nil { log.Fatal(err) } r := bufio.NewReader(f) line, _, err := r.ReadLine() for err == nil { worker(string(line),para1,para2) line, _, err = r.ReadLine() }}
日誌記錄到檔案的方法如下:
package mainimport "io"import "log"import "os"const logFileName = "test.log"func main() { logf, err := os.OpenFile(logFileName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640) if err != nil { log.Fatalln(err) } log.SetOutput(logf) mylogger := log.New(io.MultiWriter(logf,os.Stdout),"",-1) log.Println("goes to logf") mylogger.Println("goes to stdout and logf")}
日誌文本如下
2013/06/04 07:59:06 goes to logf2013/06/04 07:59:06.526852 test.go:17: goes to stdout and logf
不知道如何做效能對比,不過從運行結果來看,cpu佔用比python低非常多