Golang 实现文件解压缩与拷贝

jopen 11年前

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)  }