Go语言中如何进行文件操作:复制文件的指南

发表时间: 2024-05-24 11:35

复制文件(io.copy)

们先看下原型声明:

func Copy(dst Writer, src Reader) (written int64, err error) {return copyBuffer(dst, src, nil)}func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {......if buf == nil {size := 32 * 1024if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {if l.N < 1 {size = 1} else {size = int(l.N)}}buf = make([]byte, size)}......}

它是将源复制到目标, 而且是按默认的缓冲区32k循环操做的, 不会将内容一次性全写入内存中, 能够防止产生内存溢出, 特别是超大文件。

使用案例: 复制文件

package mainimport (    "fmt"    "io"    "log"    "os")// 封装 复制文件的方法 已经复制的情况下,可以重复复制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()    // 开始复制    size, err := io.Copy(destination, source)    return size, err}func main() {    filesize, err := copy("context.zip", "xuchenkai.zip")    if err != nil {    log.Printf("%v", err)    }    log.Printf("文件已经复制成功, 大小:%v", filesize)}

使用案例: 下载文件

package mainimport (    "io"    "net/http"    "os")func main() {    imgUrl := "https://www.twle.cn/static/i/img1.jpg"    // Get the data    resp, err := http.Get(imgUrl)    if err != nil {    panic(err)    }    defer resp.Body.Close()    /*    //方式一: ioutil.ReadAll    // 使用 ioutil.ReadAll(resp.Body) 先将所有的响应读出来放到内存中。如果文件太大,那么就会消耗很多内存, 导致内存溢出。    data, err := ioutil.ReadAll(resp.Body)    if err != nil {    panic(err)    }    ioutil.WriteFile("img1.jpg", data, 0644)    */    // 方式二: io.Copy    // 创建一个文件用于保存    out, err := os.Create("img1.jpg")    if err != nil {    panic(err)    }    defer out.Close()    // 然后将响应流和文件流对接起来    _, err = io.Copy(out, resp.Body)    if err != nil {        panic(err)    }}