Golang 實現文件解壓縮與拷貝

jopen 10年前發布 | 48K 次閱讀 Google Go/Golang開發 Golang

Golang 實現文件解壓縮與拷貝

package main

import ( "archive/tar" "compress/gzip" "fmt" "io" "os" "path" )

// main functions shows how to TarGz a directory/file and // UnTarGz a file // Gzip and tar from source directory or file to destination file // you need check file exist before you call this function

func main() { os.Mkdir("/home/ty4z2008/tar", 0777) w, err := CopyFile("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/src/1.pdf") //targetfile,sourcefile if err != nil { fmt.Println(err.Error()) } fmt.Println(w)

TarGz("/home/ty4z2008/tar/1.pdf", "/home/ty4z2008/test.tar.gz") //壓縮
//UnTarGz("/home/ty4z2008/1.tar.gz", "/home/ty4z2008")     //解壓
os.RemoveAll("/home/ty4z2008/tar")

fmt.Println("ok")

}

func TarGz(srcDirPath string, destFilePath string) { fw, err := os.Create(destFilePath) if err != nil { panic(err) } defer fw.Close()

// Gzip writer
gw := gzip.NewWriter(fw)
defer gw.Close()

// Tar writer
tw := tar.NewWriter(gw)
defer tw.Close()

// Check if it's a file or a directory
f, err := os.Open(srcDirPath)
if err != nil {
    panic(err)
}
fi, err := f.Stat()
if err != nil {
    panic(err)
}
if fi.IsDir() {
    // handle source directory
    fmt.Println("Cerating tar.gz from directory...")
    tarGzDir(srcDirPath, path.Base(srcDirPath), tw)
} else {
    // handle file directly
    fmt.Println("Cerating tar.gz from " + fi.Name() + "...")
    tarGzFile(srcDirPath, fi.Name(), tw, fi)
}
fmt.Println("Well done!")

}

// Deal with directories // if find files, handle them with tarGzFile // Every recurrence append the base path to the recPath // recPath is the path inside of tar.gz func tarGzDir(srcDirPath string, recPath string, tw *tar.Writer) { // Open source diretory dir, err := os.Open(srcDirPath) if err != nil { panic(err) } defer dir.Close()

// Get file info slice
fis, err := dir.Readdir(0)
if err != nil {
    panic(err)
}
for _, fi := range fis {
    // Append path
    curPath := srcDirPath + "/" + fi.Name()
    // Check it is directory or file
    if fi.IsDir() {
        // Directory
        // (Directory won't add unitl all subfiles are added)
        fmt.Printf("Adding path...%s\n", curPath)
        tarGzDir(curPath, recPath+"/"+fi.Name(), tw)
    } else {
        // File
        fmt.Printf("Adding file...%s\n", curPath)
    }

    tarGzFile(curPath, recPath+"/"+fi.Name(), tw, fi)
}

}

// Deal with files func tarGzFile(srcFile string, recPath string, tw *tar.Writer, fi os.FileInfo) { if fi.IsDir() { // Create tar header hdr := new(tar.Header) // if last character of header name is '/' it also can be directory // but if you don't set Typeflag, error will occur when you untargz hdr.Name = recPath + "/" hdr.Typeflag = tar.TypeDir hdr.Size = 0 //hdr.Mode = 0755 | c_ISDIR hdr.Mode = int64(fi.Mode()) hdr.ModTime = fi.ModTime()

    // Write hander
    err := tw.WriteHeader(hdr)
    if err != nil {
        panic(err)
    }
} else {
    // File reader
    fr, err := os.Open(srcFile)
    if err != nil {
        panic(err)
    }
    defer fr.Close()

    // Create tar header
    hdr := new(tar.Header)
    hdr.Name = recPath
    hdr.Size = fi.Size()
    hdr.Mode = int64(fi.Mode())
    hdr.ModTime = fi.ModTime()

    // Write hander
    err = tw.WriteHeader(hdr)
    if err != nil {
        panic(err)
    }

    // Write file data
    _, err = io.Copy(tw, fr)
    if err != nil {
        panic(err)
    }
}

}

// Ungzip and untar from source file to destination directory // you need check file exist before you call this function func UnTarGz(srcFilePath string, destDirPath string) { fmt.Println("UnTarGzing " + srcFilePath + "...") // Create destination directory os.Mkdir(destDirPath, os.ModePerm)

fr, err := os.Open(srcFilePath)
if err != nil {
    panic(err)
}
defer fr.Close()

// Gzip reader
gr, err := gzip.NewReader(fr)
if err != nil {
    panic(err)
}
defer gr.Close()

// Tar reader
tr := tar.NewReader(gr)

for {
    hdr, err := tr.Next()
    if err == io.EOF {
        // End of tar archive
        break
    }
    //handleError(err)
    fmt.Println("UnTarGzing file..." + hdr.Name)
    // Check if it is diretory or file
    if hdr.Typeflag != tar.TypeDir {
        // Get files from archive
        // Create diretory before create file
        os.MkdirAll(destDirPath+"/"+path.Dir(hdr.Name), os.ModePerm)
        // Write data to file
        fw, _ := os.Create(destDirPath + "/" + hdr.Name)
        if err != nil {
            panic(err)
        }
        _, err = io.Copy(fw, tr)
        if err != nil {
            panic(err)
        }
    }
}
fmt.Println("Well done!")

}

//Copyfile func CopyFile(dstName, srcName string) (written int64, err error) { src, err := os.Open(srcName) if err != nil { return } defer src.Close() dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644) if err != nil { return } defer dst.Close() return io.Copy(dst, src) }</pre></span>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!