成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在 Go 中復制文件的三種方法

開發(fā)
本文將介紹展示如何使用 Go 編程語言 來復制文件。在 Go 中復制文件的方法有很多,我只介紹三種最常見的:使用 Go 庫中的 io.Copy() 函數調用、一次讀取輸入文件并將其寫入另一個文件,以及使用緩沖區(qū)一塊塊地復制文件。

本文將介紹展示如何使用 Go 編程語言 來復制文件。在 Go 中復制文件的方法有很多,我只介紹三種最常見的:使用 Go 庫中的 io.Copy() 函數調用、一次讀取輸入文件并將其寫入另一個文件,以及使用緩沖區(qū)一塊塊地復制文件。

方法一:使用 io.Copy()

第一種方法就是使用 Go 標準庫的 io.Copy() 函數。你可以在 copy() 函數的代碼中找到它的實現邏輯,如下所示:

    func copy(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}

首先,上述代碼做了兩個判斷,以便確定它可以被打開讀取:一是判斷將要復制的文件是否存在(os.Stat(src)),二是判斷它是否為常規(guī)文件(sourceFileStat.Mode().IsRegular())。剩下的所有工作都由 io.Copy(destination, source) 這行代碼來完成。io.Copy() 函數執(zhí)行結束后,會返回復制的字節(jié)數和復制過程中發(fā)生的第一條錯誤消息。在 Go 中,如果沒有錯誤消息,錯誤變量的值就為 nil。

你可以在 io 包 的文檔頁面了解有關 io.Copy() 函數的更多信息。

運行 cp1.go 將產生以下輸出:

    $ go run cp1.go
Please provide two command line arguments!
$ go run cp1.go fileCP.txt /tmp/fileCPCOPY
Copied 3826 bytes!
$ diff fileCP.txt /tmp/fileCPCOPY

這個方法已經非常簡單了,不過它沒有為開發(fā)者提供靈活性。這并不總是一件壞事,但是,有些時候,開發(fā)者可能會需要/想要告訴程序該如何讀取文件。

方法二:使用 ioutil.WriteFile() 和 ioutil.ReadFile()

復制文件的第二種方法是使用 ioutil.ReadFile() 和 ioutil.WriteFile() 函數。第一個函數用于將整個文件的內容,一次性地讀入到某個內存中的字節(jié)切片里;第二個函數則用于將字節(jié)切片的內容寫入到一個磁盤文件中。

實現代碼如下:

    input, err := ioutil.ReadFile(sourceFile)
if err != nil {
fmt.Println(err)
return
}
err = ioutil.WriteFile(destinationFile, input, 0644)
if err != nil {
fmt.Println("Error creating", destinationFile)
fmt.Println(err)
return
}

上述代碼包括了兩個 if 代碼塊(嗯,用 Go 寫程序就是這樣的),程序的實際功能其實體現在 ioutil.ReadFile() 和 ioutil.WriteFile() 這兩行代碼中。

運行 cp2.go,你會得到下面的輸出:

    $ go run cp2.go
Please provide two command line arguments!
$ go run cp2.go fileCP.txt /tmp/copyFileCP
$ diff fileCP.txt /tmp/copyFileCP

請注意,雖然這種方法能夠實現文件復制,但它在復制大文件時的效率可能不高。這是因為當文件很大時,ioutil.ReadFile() 返回的字節(jié)切片會很大。

方法三:使用 os.Read() 和 os.Write()

在 Go 中復制文件的第三種方法就是下面要介紹的 cp3.go。它接受三個參數:輸入文件名、輸出文件名和緩沖區(qū)大小。

cp3.go 最重要的部分位于以下 for 循環(huán)中,你可以在 copy() 函數中找到它,如下所示:

    buf := make([]byte, BUFFERSIZE)
for {
n, err := source.Read(buf)
if err != nil && err != io.EOF {
return err
}
if n == 0 {
break
}
if _, err := destination.Write(buf[:n]); err != nil {
return err
}
}

該方法使用 os.Read() 將輸入文件的一小部分讀入名為 buf 的緩沖區(qū),然后使用 os.Write() 將該緩沖區(qū)的內容寫入文件。當讀取出錯或到達文件末尾(io.EOF)時,復制過程將停止。

運行 cp3.go,你會得到下面的輸出:

    $ go run cp3.go
usage: cp3 source destination BUFFERSIZE
$ go run cp3.go fileCP.txt /tmp/buf10 10
Copying fileCP.txt to /tmp/buf10
$ go run cp3.go fileCP.txt /tmp/buf20 20
Copying fileCP.txt to /tmp/buf20

在接下來的基準測試中,你會發(fā)現,緩沖區(qū)的大小極大地影響了 cp3.go 的性能。

運行基準測試

在本文的最后一部分,我將嘗試比較這三個程序以及 cp3.go 在不同緩沖區(qū)大小下的性能(使用 time(1) 命令行工具)。

以下輸出顯示了復制 500MB 大小的文件時,cp1.go、cp2.go 和 cp3.go 的性能對比:

    $ ls -l INPUT
-rw-r--r-- 1 mtsouk staff 512000000 Jun 5 09:39 INPUT
$ time go run cp1.go INPUT /tmp/cp1
Copied 512000000 bytes!
real 0m0.980s
user 0m0.219s
sys 0m0.719s
$ time go run cp2.go INPUT /tmp/cp2
real 0m1.139s
user 0m0.196s
sys 0m0.654s
$ time go run cp3.go INPUT /tmp/cp3 1000000
Copying INPUT to /tmp/cp3
real 0m1.025s
user 0m0.195s
sys 0m0.486s

我們可以看出,這三個程序的性能非常接近,這意味著 Go 標準庫函數的實現非常聰明、經過了充分優(yōu)化。

現在,讓我們測試一下緩沖區(qū)大小對 cp3.go 的性能有什么影響吧!執(zhí)行 cp3.go,并分別指定緩沖區(qū)大小為 10、20 和 1000 字節(jié),在一臺運行很快的機器上復制 500MB 文件,得到的結果如下:

    $ ls -l INPUT
-rw-r--r-- 1 mtsouk staff 512000000 Jun 5 09:39 INPUT
$ time go run cp3.go INPUT /tmp/buf10 10
Copying INPUT to /tmp/buf10
real 6m39.721s
user 1m18.457s
sys 5m19.186s
$ time go run cp3.go INPUT /tmp/buf20 20
Copying INPUT to /tmp/buf20
real 3m20.819s
user 0m39.444s
sys 2m40.380s
$ time go run cp3.go INPUT /tmp/buf1000 1000
Copying INPUT to /tmp/buf1000
real 0m4.916s
user 0m1.001s
sys 0m3.986s

我們可以發(fā)現,緩沖區(qū)越大,cp3.go 運行得就越快,這或多或少是符合預期的。此外,使用小于 20 字節(jié)的緩沖區(qū)來復制大文件會非常緩慢,應該避免。

你可以在 GitHub 找到 cp1.go、cp2.go 和 cp3.go 的 Go 代碼。

責任編輯:未麗燕 來源: Linux中國
相關推薦

2010-10-20 13:52:07

SQL Server數

2023-08-15 08:01:07

Go 語言排序

2016-10-12 13:53:38

JavaByteBufferRandomAcces

2010-09-08 13:29:48

CSS

2022-11-18 15:09:29

2022-08-19 11:17:09

Linux

2018-09-26 10:22:03

2021-12-20 07:11:26

Java List排序 Java 基礎

2009-07-08 12:56:32

編寫Servlet

2022-05-30 07:07:35

Java監(jiān)聽文件Java 8

2011-06-10 10:43:12

Ubuntu應用安裝

2009-06-23 10:45:18

Hibernate支持

2019-07-02 17:34:42

2010-09-14 15:10:49

CSS注釋

2024-11-15 07:00:00

Python發(fā)送郵件

2022-07-13 16:06:16

Python參數代碼

2011-04-18 15:32:45

游戲測試測試方法軟件測試

2009-12-11 18:49:39

預算編制博科資訊

2023-08-14 17:58:13

RequestHTTP請求

2023-03-10 08:57:19

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩国产精品一区 | 成人国产免费视频 | 91免费观看| 国产成人精品午夜 | 成人免费视频网站在线看 | h视频在线播放 | 亚洲精品一区二区三区中文字幕 | 超碰精品在线观看 | 成人免费视频网站在线看 | 视频三区 | 一区二区三区国产精品 | 久干网| 成人av一区二区在线观看 | 亚洲一区二区中文字幕 | 91天堂网| 特黄毛片 | 日韩久久久久 | av资源中文在线天堂 | 男人天堂网址 | av黄色在线 | 亚洲伦理自拍 | 亚洲国产精品久久人人爱 | 日韩中文字幕在线不卡 | 免费看黄色国产 | jizz在线免费观看 | 精品国产欧美一区二区三区不卡 | 国内精品一区二区三区 | 亚洲精品免费视频 | 亚洲欧美日韩电影 | 欧美精品欧美精品系列 | 视频一区在线观看 | 亚洲视频在线观看 | av一区二区三区四区 | 视频一区 亚洲 | 国产日韩在线观看一区 | 九九九视频在线观看 | 成人超碰| 青青草视频免费观看 | 日韩午夜激情 | 在线视频国产一区 | 国产日韩一区 |