golang–archive/tar
golang–archive/tar
index
- type FormatFormat 類型裡面是各種tar包的格式,具體格式內容參考GUN tar man page
- func (f Format) String() string
- type Header
tar 文件頭部信息
- func FileInfoHeader(fi os.FileInfo, link string) (*Header, error)FileInfoHeader 的作用是將 FileInfo 實例轉化為tar的Header,但轉化的Header並不完全,例如name只是basename,而不是fullname(全路徑),當文件為軟連接文件的時候,link欄位為源文件
的全路徑
- func (h *Header) FileInfo() os.FileInfo將tar.Header 轉化為os.FileInfo
- type ReaderReader提供對tar文件的順序訪問,Reader.Next進入tar存檔的下一個文件(包括第一個文件),Reader可以作為io.Reader介面來訪問文件的數據
- func NewReader(r io.Reader) *Reader
從一個io.Reader介面類型創建一個tar.Reader的結構體
func (tr *Reader) Next() (*Header, error)
讀取下一個文件Headerfunc (tr *Reader) Read(b []byte) (int, error)
讀取文件內容
- type WriterWriter類型提供給tar文件的順序寫入,Write.WriteHeader從給定的第一個Header開始,可以將Writer視為io.Writer來提供該文件的數據
- func NewWriter(w io.Writer) *Writer創建一個新的tar.Writer
- func (tw *Writer) Close() error關閉打開的wirter,同時寫入數據。必須調用close方法,結束文件讀寫,close會向tar文件寫入結束欄位
- func (tw *Writer) Flush() error將數據寫入tar文件
func (tw *Writer) Write(b []byte) (int, error)
將數據寫入當前存檔文件。如果在writeHeader之後寫入超過Header.Size位元組,則Write返回ErrWriteTooLong錯誤
- func (tw *Writer) WriteHeader(hdr *Header) error將文件頭部信心hdr寫入當前的tar文件
Tar程序思路:
- 了解tar文件結構
- 如何獲取文件信息,寫入tar文件
- 創建tar文件,判斷是否存在,存在是否覆蓋
- 如何寫入多個文件和目錄
package main ? // 非正常文件,如:軟連接,硬鏈接文件沒有處理,打包文件存在沒有處理 import ( "archive/tar" "fmt" "io" "os" ? "path/filepath" ) ? var ( fileAllList []newFileInfo //文件信息列表 ) ? type newFileInfo struct { fileFullName string fileinfo os.FileInfo } ? func main() { if len(os.Args) <= 1 { fmt.Println("No args ") help() os.Exit(2) } ? fileArg := os.Args[1:] fileTar := fileArg[0] fileList := fileArg[1:] ? // fmt.Println(fileTar, fileList) ? // 創建tar文件 var fileTarW *tar.Writer if _, err := os.Stat(fileTar); err != nil { if os.IsNotExist(err) { fmt.Println(err) w, err := os.Create(fileTar) if err != nil { panic(err) } defer w.Close() ? fileTarW = tar.NewWriter(w) if err != nil { panic(err) } defer fileTarW.Close() ? } else { fmt.Println(err) panic(err) } } ? for _, file := range fileList { fileStat, err := os.Stat(file) if err != nil { fmt.Println(err) os.Exit(3) } // 判斷參數是文件或文件夾 if fileStat.IsDir() { err = filepath.Walk(file, walkFunc) if err != nil { fmt.Println(err) os.Exit(2) } ? } else { ? fileAllList = append(fileAllList, newFileInfo{ file, fileStat, }) } ? } ? for _, f := range fileAllList { // fmt.Println(f.fileFullName) err := addToTar(f.fileFullName, f.fileinfo, fileTarW) if err != nil { fmt.Println("123") panic(err) } } ? } ? func help() { fmt.Println("xintar *.tar file1 file2 dir1 dir2") ? } // walk方法會調用walkFunc方法,通過這個方法將文件加入fileAllList func walkFunc(path string, info os.FileInfo, err error) error { if !info.IsDir() { fileAllList = append(fileAllList, newFileInfo{path, info}) //fmt.Println(path, "----", info.Name()) return nil } else { return nil } } ? //將文件寫入tar文件 func addToTar(name string, info os.FileInfo, tarw *tar.Writer) error { file, err := os.Open(name) if err != nil { return err } defer file.Close() ? fileTarInfo, _ := tar.FileInfoHeader(info, "") fileTarInfo.Name = name err = tarw.WriteHeader(fileTarInfo) if err != nil { return err } _, err = io.Copy(tarw, file) if err != nil { return err } tarw.Flush() return nil }
推薦閱讀:
※蘋果推出新款拆卸機器人能夠拆解九個版本的iPhone
※後監管時代的區塊鏈世界
※沖100mWIFI流量到手機裡面然後到無WIFI的地方用這100m來上網,什麼時候可以這樣?
※有哪些冷門但好用的Word技巧?
※軸承跑內圈後如何緊急修復?
TAG:科技 |