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