dtbc37573 2018-07-14 03:29
浏览 140
已采纳

io.Copy比调用mv命令慢很多

It seems io.Copy is slow for me:

   _,err = io.Copy(destf,srcf)

io.Copy takes longer, about 2 minutes to copy a 1GB file to a network share. Noticed that mv.exe finishes the job in ~25 seconds max - so I've started to evoke mv for my jobs.

    output, err := exec.Command("mv", src, dest_folder).CombinedOutput()

This slowness is consistently reproducible on my end, Any tips on how to speeden will be much appreciated!

Update:

Thanks for the suggestion to use io.CopyBuffer(), however mv.exe still emerges as the sole victor, by a respectable margin.

Details:

PS C:\temp> .\move_files.exe .\testfile.data "\\somehost\somefolder\bleh13.txt"
2018/07/14 19:04:54 Created C:\Temp\2\deleteME__913153343, copy of .\testfile.data, Size: 1073745920 bytes
2018/07/14 19:05:55 Transfer with io.Copy() took us 60.836702 seconds
2018/07/14 19:06:47 Transfer with io.CopyBuffer() took us 50.729625 seconds
2018/07/14 19:06:59 Transfer with mv command took us 11.470456 seconds
PS C:\temp>

You're welcome to try this yourself : https://play.golang.org/p/2_lR83A4BXe

  • 写回答

3条回答 默认 最新

  • douqin2108 2018-07-15 17:23
    关注

    Continuing my comment suggesting to try the CopyFile Win32 API function, here's a working program which wraps it:

    package main
    
    import (
        "log"
        "os"
        "syscall"
        "unsafe"
    )
    
    var (
        kernel32     = syscall.MustLoadDLL("kernel32.dll")
        copyFileProc = kernel32.MustFindProc("CopyFileW")
    )
    
    func CopyFile(src, dst string, overwrite bool) error {
        srcW := syscall.StringToUTF16(src)
        dstW := syscall.StringToUTF16(dst)
    
        var failIfExists uintptr
        if overwrite {
            failIfExists = 0
        } else {
            failIfExists = 1
        }
    
        rc, _, err := copyFileProc.Call(
            uintptr(unsafe.Pointer(&srcW[0])),
            uintptr(unsafe.Pointer(&dstW[0])),
            failIfExists)
        if rc == 0 {
            return &os.PathError{
                Op:   "CopyFile",
                Path: src,
                Err:  err,
            }
        }
        return nil
    }
    
    func main() {
        log.SetFlags(0)
    
        if len(os.Args) != 3 {
            log.Fatalf("Wrong # args.
    Usage: %s SOURCE DEST
    ", os.Args[0])
        }
    
        err := CopyFile(os.Args[1], os.Args[2], false)
        if err != nil {
            log.Fatal("error copying file: ", err)
        }
    }
    

    Please try it and see whether it improves over io.Copy*.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题