脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - GO语言实现简单的目录复制功能

GO语言实现简单的目录复制功能

2020-04-11 11:41shichen2014 Golang

这篇文章主要介绍了GO语言实现简单的目录复制功能,通过新建及复制内容等操作最终实现复制目录的功能效果,具有一定的参考借鉴价值,需要的朋友可以参考下

本文实例讲述了GO语言实现简单的目录复制功能。分享给大家供大家参考。具体实现方法如下:

创建一个独立的 goroutine 遍历文件,主进程负责写入数据。程序会复制空目录,也可以设置只复制以 ".xx" 结尾的文件。
严格来说这不是复制文件,而是写入新文件。因为这个程序是创建新文件,然后写入复制数据的。我们一般的 copy 命令是不会修改文件的 ctime(change time) 状态的。

GO语言实现简单的目录复制功能

代码如下:

复制代码 代码如下:

// 一个简单的目录复制程序:一个独立的 goroutine 遍历目录,主进程负责将数据写入新目录。
// 2014-11-02 Bing.L
package main

 

import (
 "io"
 "log"
 "os"
 "path/filepath"
 "strings"
)

type FileInfo struct {
 RelPath string
 Size    int64
 IsDir   bool
 Handle  *os.File
}

//复制文件数据
func ioCopy(srcHandle *os.File, dstPth string) (err error) {
 dstHandle, err := os.OpenFile(dstPth, os.O_CREATE|os.O_WRONLY, os.ModePerm)
 if err != nil {
  return err
 }

 defer srcHandle.Close()
 defer dstHandle.Close()

 _, err = io.Copy(dstHandle, srcHandle)
 return err
}

//遍历目录,将文件信息传入通道
func WalkFiles(srcDir, suffix string, c chan<- *FileInfo) {
 suffix = strings.ToUpper(suffix)

 filepath.Walk(srcDir, func(f string, fi os.FileInfo, err error) error { //遍历目录
  if err != nil {
   log.Println("[E]", err)
  }

  fileInfo := &FileInfo{}
  if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { //匹配文件
   if fh, err := os.OpenFile(f, os.O_RDONLY, os.ModePerm); err != nil {
    log.Println("[E]", err)
   } else {
    fileInfo.Handle = fh
    fileInfo.RelPath, _ = filepath.Rel(srcDir, f) //相对路径
    fileInfo.Size = fi.Size()
    fileInfo.IsDir = fi.IsDir()
   }

   c <- fileInfo
  }
 })
 close(c) //遍历完成,关闭通道
}

//写目标文件
func WriteFiles(dstDir string, c <-chan *FileInfo) {
 if err := os.Chdir(dstDir); err != nil { //切换工作路径
  log.Fatalln("[F]", err)
 }

 for f := range c {
  if fi, err := os.Stat(f.RelPath); os.IsNotExist(err) { //目标不存在
   if f.IsDir {
    if err := os.MkdirAll(f.RelPath, os.ModeDir); err != nil {
     log.Println("[E]", err)
    }
   } else {
    if err := ioCopy(f.Handle, f.RelPath); err != nil {
     log.Println("[E]", err)
    } else {
     log.Println("[I] CP:", f.RelPath)
    }
   }
  } else if !f.IsDir { //目标存在,而且源不是一个目录

   if fi.IsDir() != f.IsDir { //检查文件名被目录名占用冲突
    log.Println("[E]", "filename conflict:", f.RelPath)

   } else if fi.Size() != f.Size { //源和目标的大小不一致时才重写
    if err := ioCopy(f.Handle, f.RelPath); err != nil {
     log.Println("[E]", err)
    } else {
     log.Println("[I] CP:", f.RelPath)
    }
   }
  }
 }
}

func main() {
 files_ch := make(chan *FileInfo, 100)

 go WalkFiles("E:\\study", ".doc", files_ch) //在一个独立的 goroutine 中遍历文件
 WriteFiles("E:\\study.bak", files_ch)
}

 

希望本文所述对大家的GO语言程序设计有所帮助。

延伸 · 阅读

精彩推荐
  • GolangGO语言字符串处理Strings包的函数使用示例讲解

    GO语言字符串处理Strings包的函数使用示例讲解

    这篇文章主要为大家介绍了GO语言字符串处理Strings包的函数使用示例讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加...

    Jeff的技术栈6882022-04-14
  • GolangGo语言基础单元测试与性能测试示例详解

    Go语言基础单元测试与性能测试示例详解

    这篇文章主要为大家介绍了Go语言基础单元测试与性能测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步...

    枫少文7812021-12-05
  • Golanggo语言获取系统盘符的方法

    go语言获取系统盘符的方法

    这篇文章主要介绍了go语言获取系统盘符的方法,涉及Go语言调用winapi获取系统硬件信息的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    无尽海3862020-04-24
  • GolangGolang实现四种负载均衡的算法(随机,轮询等)

    Golang实现四种负载均衡的算法(随机,轮询等)

    本文介绍了示例介绍了Golang 负载均衡的四种实现,主要包括了随机,轮询,加权轮询负载,一致性hash,感兴趣的小伙伴们可以参考一下...

    Gundy_8442021-08-09
  • Golang深入浅析Go中三个点(...)用法

    深入浅析Go中三个点(...)用法

    这篇文章主要介绍了深入浅析Go中三个点(...)用法,需要的朋友可以参考下...

    踏雪无痕SS6472021-11-17
  • GolangGo语言实现自动填写古诗词实例代码

    Go语言实现自动填写古诗词实例代码

    这篇文章主要给大家介绍了关于Go语言实现自动填写古诗词的相关资料,这是最近在项目中遇到的一个需求,文中通过示例代码介绍的非常详细,需要的朋...

    FengY5862020-05-14
  • GolangGo语言range关键字循环时的坑

    Go语言range关键字循环时的坑

    今天小编就为大家分享一篇关于Go语言range关键字循环时的坑,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    benben_20154202020-05-23
  • GolangGolang 语言极简类型转换库cast的使用详解

    Golang 语言极简类型转换库cast的使用详解

    本文我们通过 cast.ToString() 函数的使用,简单介绍了cast 的使用方法,除此之外,它还支持很多其他类型,在这没有多多介绍,对Golang 类型转换库 cast相关知...

    Golang语言开发栈6112021-12-02