GO语言实现简单的目录复制功能
作者:shichen2014 发布时间:2024-04-26 17:21:39
本文实例讲述了GO语言实现简单的目录复制功能。分享给大家供大家参考。具体实现方法如下:
创建一个独立的 goroutine 遍历文件,主进程负责写入数据。程序会复制空目录,也可以设置只复制以 ".xx" 结尾的文件。
严格来说这不是复制文件,而是写入新文件。因为这个程序是创建新文件,然后写入复制数据的。我们一般的 copy 命令是不会修改文件的 ctime(change time) 状态的。
代码如下:
// 一个简单的目录复制程序:一个独立的 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语言程序设计有所帮助。
猜你喜欢
- 如下所示:#coding=utf-8#布局自定义尺寸from tkinter import *class App:def __init__(
- 在软件开发过程中经常会遇到数据库升迁的问题,原因比较多,如acsess访问速度比sql server慢、删除数据记录后access会留下空档
- bootstrap的button边框问题最近在线上学习bootstrap时,发现很多童鞋都会遇到很多坑,有些很容易掉进去就出不来了;boot
- 首先贴一张验证码上来做案例:第一步先通过二值化处理把干扰线去掉:from PIL import Image# 二值化处理def two_va
- 本文实例讲述了python实现的自动发送消息功能。分享给大家供大家参考,具体如下:一个简单的脚本#-*- coding:utf-8 -*-f
- sysbench是一个模块化的、跨平台、多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况。关于这个项目的详细介绍请看:
- 在python3爬虫中如何我们想要导入/导出Redis数据,就要安装使用RedisDump。RedisDump是一个用于Redis数据导入/
- 前言 本篇章主要介绍二叉树的应用之一------二叉排序树,包括二叉排序树的定义、查找、插入、构造、删除及查找效率分析。1. 二叉排序树的
- 所谓贪婪匹配就是匹配重复字符是尽可能多的匹配,比如:"aaaaa".match(/a+/); //["aaaa
- 本文实例为大家分享了js实现微信聊天效果的具体代码,供大家参考,具体内容如下<!DOCTYPE html><html la
- 相信很多人都跟小编一样不管是什么账号,如果很久不用就会忘记登录密码,像数据库SQL Server2008也一样有用户名和登录密码,下面小编就
- Python的字符集处理实在蛋疼,目前使用UTF-8居多,然后默认使用的字符集是ascii,所以我们需要改成utf-8查看目前系统字符集im
- 1、MySQL下载1.1下载MySQL8.0.26安装与卸载的完整步骤记录MySQL关是一种关系数据库管理系统,所使用的 SQL 语言是用于
- Oracle存储过程基本语法 存储过程 1 CREATE OR REPLACE PROCEDURE 存储过程名 2 IS 3 BEGIN 4
- 阅读上一篇:浏览器中的内存泄露 4.内存泄露的解决方案显式类型转换 首先说说最容易处理的情况 对于类型转换造成的错误,我们可以通过显式类型转
- 本文实例为大家分享了python opencv实现图像配准与比较的具体代码,供大家参考,具体内容如下代码 from skimage
- 表格内容根据票据日期升序(这里是已经排序后的效果)上代码代码中data的内容如下根据paper_date排序,因为目前这种格式不支持比较,需
- 使用pycharm的时候,有时需要重命名文件,该怎么操作呢?下面小编给大家演示一下。首先准备一个要重命名的文件,如下图所示接着右键单击选择R
- 如下所示:import picklewith open(filename, 'rb') as f: datadict = p
- 本文介绍了layer弹出子iframe层父子页面传值的实现方法,分享给大家,具体如下:父页面获取子页面元素格式:$("#ifram