1.打包文件
// This example uses zip but standard library // also supports tar archives package main import ( "archive/zip" "log" "os" ) func main() { // 创建一个打包文件 outFile,err := os.Create("test.zip") if err != nil { log.Fatal(err) } defer outFile.Close() // 创建zip writer zipWriter := zip.NewWriter(outFile) // 往打包文件中写文件。 // 这里我们使用硬编码的内容,你可以遍历一个文件夹,把文件夹下的文件以及它们的内容写入到这个打包文件中。 var filesToArchive = []struct { Name,Body string } { {"test.txt","String contents of file"},{"test2.txt","\x61\x62\x63\n"},} // 下面将要打包的内容写入到打包文件中,依次写入。 for _,file := range filesToArchive { fileWriter,err := zipWriter.Create(file.Name) if err != nil { log.Fatal(err) } _,err = fileWriter.Write([]byte(file.Body)) if err != nil { log.Fatal(err) } } // 清理 err = zipWriter.Close() if err != nil { log.Fatal(err) } }
2.unzip
// This example uses zip but standard library // also supports tar archives package main import ( "archive/zip" "log" "io" "os" "path/filepath" ) func main() { zipReader,err := zip.OpenReader("test.zip") if err != nil { log.Fatal(err) } defer zipReader.Close() // 遍历打包文件中的每一文件/文件夹 for _,file := range zipReader.Reader.File { // 打包文件中的文件就像普通的一个文件对象一样 zippedFile,err := file.Open() if err != nil { log.Fatal(err) } defer zippedFile.Close() // 指定抽取的文件名。 // 你可以指定全路径名或者一个前缀,这样可以把它们放在不同的文件夹中。 // 我们这个例子使用打包文件中相同的文件名。 targetDir := "./" extractedFilePath := filepath.Join( targetDir,file.Name,) // 抽取项目或者创建文件夹 if file.FileInfo().IsDir() { // 创建文件夹并设置同样的权限 log.Println("Creating directory:",extractedFilePath) os.MkdirAll(extractedFilePath,file.Mode()) } else { //抽取正常的文件 log.Println("Extracting file:",file.Name) outputFile,err := os.OpenFile( extractedFilePath,os.O_WRONLY|os.O_CREATE|os.O_TRUNC,file.Mode(),) if err != nil { log.Fatal(err) } defer outputFile.Close() // 通过io.Copy简洁地复制文件内容 _,err = io.Copy(outputFile,zippedFile) if err != nil { log.Fatal(err) } } } }
3.压缩文件
// 这个例子中使用gzip压缩格式,标准库还支持zlib,bz2,flate,lzw package main import ( "os" "compress/gzip" "log" ) func main() { outputFile,err := os.Create("test.txt.gz") if err != nil { log.Fatal(err) } gzipWriter := gzip.NewWriter(outputFile) defer gzipWriter.Close() // 当我们写如到gizp writer数据时,它会依次压缩数据并写入到底层的文件中。 // 我们不必关心它是如何压缩的,还是像普通的writer一样操作即可。 _,err = gzipWriter.Write([]byte("Gophers rule!\n")) if err != nil { log.Fatal(err) } log.Println("Compressed data written to file.") }
4.解压缩文件
// 这个例子中使用gzip压缩格式,标准库还支持zlib,lzw package main import ( "compress/gzip" "log" "io" "os" ) func main() { // 打开一个gzip文件。 // 文件是一个reader,但是我们可以使用各种数据源,比如web服务器返回的gzipped内容, // 它的内容不是一个文件,而是一个内存流 gzipFile,err := os.Open("test.txt.gz") if err != nil { log.Fatal(err) } gzipReader,err := gzip.NewReader(gzipFile) if err != nil { log.Fatal(err) } defer gzipReader.Close() // 解压缩到一个writer,它是一个file writer outfileWriter,err := os.Create("unzipped.txt") if err != nil { log.Fatal(err) } defer outfileWriter.Close() // 复制内容 _,err = io.Copy(outfileWriter,gzipReader) if err != nil { log.Fatal(err) } }
5.临时文件和目录
IoUtil提供了两个函数: TempDir() 和 TempFile()。
使用完毕后,调用者负责删除这些临时文件和文件夹。
有一点好处就是当你传递一个空字符串作为文件夹名的时候,它会在操作系统的临时文件夹中创建这些项目(/tmp on Linux)。
os.TempDir()返回当前操作系统的临时文件夹。
package main import ( "os" "io/IoUtil" "log" "fmt" ) func main() { // 在系统临时文件夹中创建一个临时文件夹 tempDirPath,err := IoUtil.TempDir("","myTempDir") if err != nil { log.Fatal(err) } fmt.Println("Temp dir created:",tempDirPath) // 在临时文件夹中创建临时文件 tempFile,err := IoUtil.TempFile(tempDirPath,"myTempFile.txt") if err != nil { log.Fatal(err) } fmt.Println("Temp file created:",tempFile.Name()) // ... 做一些操作 ... // 关闭文件 err = tempFile.Close() if err != nil { log.Fatal(err) } // 删除我们创建的资源 err = os.Remove(tempFile.Name()) if err != nil { log.Fatal(err) } err = os.Remove(tempDirPath) if err != nil { log.Fatal(err) } }
6.通过HTTP下载文件
package main import ( "os" "io" "log" "net/http" ) func main() { newFile,err := os.Create("devdungeon.html") if err != nil { log.Fatal(err) } defer newFile.Close() url := "http://www.devdungeon.com/archive" response,err := http.Get(url) defer response.Body.Close() // 将HTTP response Body中的内容写入到文件 // Body满足reader接口,因此我们可以使用IoUtil.Copy numBytesWritten,err := io.Copy(newFile,response.Body) if err != nil { log.Fatal(err) } log.Printf("Downloaded %d byte file.\n",numBytesWritten) }
7.哈希和摘要
package main import ( "crypto/md5" "crypto/sha1" "crypto/sha256" "crypto/sha512" "log" "fmt" "io/IoUtil" ) func main() { // 得到文件内容 data,err := IoUtil.ReadFile("test.txt") if err != nil { log.Fatal(err) } // 计算Hash fmt.Printf("Md5: %x\n\n",md5.Sum(data)) fmt.Printf("Sha1: %x\n\n",sha1.Sum(data)) fmt.Printf("Sha256: %x\n\n",sha256.Sum256(data)) fmt.Printf("Sha512: %x\n\n",sha512.Sum512(data)) }
上面的例子复制整个文件内容到内存中,传递给hash函数。
另一个方式是创建一个hash writer,使用Write、WriteString、Copy将数据传给它。
下面的例子使用 md5 hash,但你可以使用其它的Writer。
package main import ( "crypto/md5" "log" "fmt" "io" "os" ) func main() { file,err := os.Open("test.txt") if err != nil { log.Fatal(err) } defer file.Close() //创建一个新的hasher,满足writer接口 hasher := md5.New() _,err = io.Copy(hasher,file) if err != nil { log.Fatal(err) } // 计算hash并打印结果。 // 传递 nil 作为参数,因为我们不通参数传递数据,而是通过writer接口。 sum := hasher.Sum(nil) fmt.Printf("Md5 checksum: %x\n",sum) }