golang 文件操做之三

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, bz2, flate, 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。html

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

原文:http://colobu.com/2016/10/12/...web

相關文章
相關標籤/搜索