在使用Go開發項目的過程中,有時我們需要做一些復制文件的功能,我們可以把它封裝成一個函數,在以后每次需要用到該功能的時候直接調用封裝的函數即可。
如果是大文件,我們可以使用os包
,使用os.Open()
和os.Create()
都可以獲取到文件句柄(文件指針),然后通過文件句柄(文件指針)的Read()
和Write()
方法,按照字節讀取和寫入來實現復制文件的功能
對於大文件,我們可以采用下面的方式
package main
import (
"io"
"log"
"os"
)
func CopyFile(srcFileName string, dstFileName string) {
//打開源文件
srcFile, err := os.Open(srcFileName)
if err != nil {
log.Fatalf("源文件讀取失敗,原因是:%v\n", err)
}
defer func() {
err = srcFile.Close()
if err != nil {
log.Fatalf("源文件關閉失敗,原因是:%v\n", err)
}
}()
//創建目標文件,稍后會向這個目標文件寫入拷貝內容
distFile, err := os.Create(dstFileName)
if err != nil {
log.Fatalf("目標文件創建失敗,原因是:%v\n", err)
}
defer func() {
err = distFile.Close()
if err != nil {
log.Fatalf("目標文件關閉失敗,原因是:%v\n", err)
}
}()
//定義指定長度的字節切片,每次最多讀取指定長度
var tmp = make([]byte, 1024*4)
//循環讀取並寫入
for {
n, err := srcFile.Read(tmp)
n, _ = distFile.Write(tmp[:n])
if err != nil {
if err == io.EOF {//讀到了文件末尾,並且寫入完畢,任務完成返回(關閉文件的操作由defer來完成)
return
} else {
log.Fatalf("拷貝過程中發生錯誤,錯誤原因為:%v\n", err)
}
}
}
}
func main() {
CopyFile("./worm.mp4", "./dist.mp4")
}
使用io包的Copy方法也能實現文件復制功能
package main
import (
"fmt"
"io"
"os"
)
//自己編寫一個函數,接收兩個文件路徑 srcFileName dstFileName
func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer srcFile.Close()
//打開dstFileName
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY | os.O_CREATE, 0755)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer dstFile.Close()
return io.Copy(dstFile, srcFile)
}
func main() {
result, err := CopyFile("./src/main/dst.png", "./src/main/file.png")
if err == nil {
fmt.Println("拷貝成功!,拷貝的字節數為: ", result)
}
}
還可以使用下面的方法
package main
import (
"bufio"
"fmt"
"io"
"os"
)
//自己編寫一個函數,接收兩個文件路徑 srcFileName dstFileName
func CopyFile(dstFileName string, srcFileName string) (written int64, err error) {
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer srcFile.Close()
//通過srcFile,獲取到Reader
reader := bufio.NewReader(srcFile)
//打開dstFileName
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY | os.O_CREATE, 0666)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
writer := bufio.NewWriter(dstFile)
defer func() {
writer.Flush() //把緩沖區的內容寫入到文件
dstFile.Close()
}()
return io.Copy(writer, reader)
}
func main() {
result, err := CopyFile("./src/main/dst.png", "./src/main/file.png")
if err == nil {
fmt.Println("拷貝成功!拷貝的字節大寫為: ", result)
}
}