SoFunction
Updated on 2025-03-04

GO language implements simple directory copying function

// A simple directory copy program: a separate goroutine traversal directory, and the main process is responsible for writing data to the new directory.
// 2014-11-02
package main

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

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

//Copy file data
func ioCopy(srcHandle *, dstPth string) (err error) {
 dstHandle, err := (dstPth, os.O_CREATE|os.O_WRONLY, )
 if err != nil {
  return err
 }

 defer ()
 defer ()

 _, err = (dstHandle, srcHandle)
 return err
}

//Travel over the directory and pass file information into the channel
func WalkFiles(srcDir, suffix string, c chan<- *FileInfo) {
 suffix = (suffix)

(srcDir, func(f string, fi, err error) error { //Travel the directory
  if err != nil {
   ("[E]", err)
  }

  fileInfo := &FileInfo{}
if ((()), suffix) { //Match the file
   if fh, err := (f, os.O_RDONLY, ); err != nil {
    ("[E]", err)
   } else {
     = fh
_ = (srcDir, f) //Relative path
     = ()
     = ()
   }

   c <- fileInfo
  }
 })
close(c) //The traversal is completed, the channel is closed
}

//Write the target file
func WriteFiles(dstDir string, c <-chan *FileInfo) {
if err := (dstDir); err != nil { //Switch working path
  ("[F]", err)
 }

 for f := range c {
if fi, err := (); (err) { //The target does not exist
   if {
    if err := (, ); err != nil {
     ("[E]", err)
    }
   } else {
    if err := ioCopy(, ); err != nil {
     ("[E]", err)
    } else {
     ("[I] CP:", )
    }
   }
} else if ! { //The target exists, and the source is not a directory

if () != { //Check the file name to conflict with directory name occupation
    ("[E]", "filename conflict:", )

} else if () != { //Rewrite only if the sizes of the source and the target are inconsistent
    if err := ioCopy(, ); err != nil {
     ("[E]", err)
    } else {
     ("[I] CP:", )
    }
   }
  }
 }
}

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

go WalkFiles("E:\\study", ".doc", files_ch) //Transfer files in a separate goroutine
 WriteFiles("E:\\", files_ch)
}