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 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化