无法使用golang删除解压缩的文件夹

Unable to delete an unzipped folder using golang

我编写了将文件解压缩到特定位置的代码,然后将文件夹的内容复制到文件夹解压缩的外部,然后删除该文件夹。

这是我写的代码:

package main

 import (
   "os"
   "flag"
   "fmt"
   "io"
   "path/filepath"
   "os/exec"
   "archive/zip"
   "time"
 )

func RemoveContents(dir string) error {
    d, err := os.Open(dir)
    if err != nil {
        return err
    }
    names, err := d.Readdirnames(-1)
    if err != nil {
        return err
    }
    for _, name := range names { 
            err = os.RemoveAll(filepath.Join(dir, name))
            if err != nil {
                return err
            }
    }
    d.Close()
    return nil
}


func CopyFile(source string, dest string) (err error) {
     sourcefile, err := os.Open(source)
     if err != nil {
         return err
     }

     defer sourcefile.Close()

     destfile, err := os.Create(dest)
     if err != nil {
         return err
     }

     defer destfile.Close()

     _, err = io.Copy(destfile, sourcefile)
     if err == nil {
         sourceinfo, err := os.Stat(source)
         if err != nil {
             err = os.Chmod(dest, sourceinfo.Mode())
         }

     }

     return
 }

 func CopyDir(source string, dest string) (err error) {

     // get properties of source dir
     sourceinfo, err := os.Stat(source)
     if err != nil {
         return err
     }

     // create dest dir

     err = os.MkdirAll(dest, sourceinfo.Mode())
     if err != nil {
         return err
     }

     directory, _ := os.Open(source)

     objects, err := directory.Readdir(-1)

     for _, obj := range objects {

         sourcefilepointer := source + "/" + obj.Name()

         destinationfilepointer := dest + "/" + obj.Name()


         if obj.IsDir() {
             // create sub-directories - recursively
             err = CopyDir(sourcefilepointer, destinationfilepointer)
             if err != nil {
                 fmt.Println(err)
             }
         } else {
             // perform copy
             err = CopyFile(sourcefilepointer, destinationfilepointer)
             if err != nil {
                 fmt.Println(err)
             }
         }

     }
     return
 }




 func main() {
    flag.Parse() // get the source and destination directory

    source_dir := flag.Arg(0) // get the source directory from 1st argument

    dest_dir := flag.Arg(1) // get the destination directory from the 2nd argument

        os.MkdirAll("E:\go\copyDirectory\myFile.zip",0777)
    zipFilePath := "E:\go\copyDirectory\myFile.zip"
    tempWrkDir := "E:\go\copyDirectory\"

    //Read zip file and get path handle.
    fileHandleReader, err := zip.OpenReader(zipFilePath)
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
    //open zip file and read all the folder and files inside
    for _, fileReadHandler := range fileHandleReader.Reader.File {
        //read the file or folder handle inside zip
        fileOpenHandle, err := fileReadHandler.Open()
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        defer fileOpenHandle.Close()
    targetUnZipPath := filepath.Join(tempWrkDir, fileReadHandler.Name)
    if fileReadHandler.FileInfo().IsDir() {
            os.MkdirAll(targetUnZipPath, fileReadHandler.Mode())
            //fmt.Println("Creating directory", path)
        }else {
            // create new dummy file to copy original file.
            newTempFileHandle, err := os.OpenFile(targetUnZipPath, os.O_WRONLY|os.O_CREATE, fileReadHandler.Mode())

            if err != nil {
                fmt.Println(err)
                os.Exit(1)
            }

            defer newTempFileHandle.Close()
            //copying original file to dummy file.
            if _, err = io.Copy(newTempFileHandle, fileOpenHandle); err != nil {
                fmt.Println(err)
                os.Exit(1)
            }
        }
    }
      time.Sleep(1000*time.Millisecond)

      fmt.Println("Source :" + source_dir)

      // check if the source dir exist
      src, err := os.Stat(source_dir)
     if err != nil {
       panic(err)
    }

     if !src.IsDir() {
       fmt.Println("Source is not a directory")
       os.Exit(1)
    }

   // create the destination directory
   fmt.Println("Destination :"+ dest_dir)

   /*_, err = os.Open(dest_dir)
   if !os.IsNotExist(err) {
     fmt.Println("Destination directory already exists. Abort!")
     os.Exit(1)
   }*/

   err = CopyDir(source_dir, dest_dir)
   if err != nil {
      fmt.Println(err)
   } else {
      fmt.Println("Directory copied")
   }
    err = RemoveContents("./myFiles")
       if err != nil {
        fmt.Println("ERRR:::",err)
       }
    //time.Sleep(10000*time.Millisecond)
 }

问题是除了删除文件夹外一切正常。该文件夹中只有一个文件。文件位置如下:

E:\go\copyDirectory\myfile\mytextfile.txt

压缩文件的位置如下:

 E:\go\copyDirectory\myfile.zip

压缩文件只有一个文本文件。 zip文件里面的文件如下:

E:\go\copyDirectory\myfile.zip\myfile\mytextfile.txt

我得到的错误是:

ERRR::: remove myfile\mytextfile.txt: The process cannot
access the file because it is being used by another process.

提前致谢。

您没有关闭文件。这个:

defer newTempFileHandle.Close()

是运行当main完成的时候,也就是在:

之后
err = RemoveContents("./myFiles")

您可以将那段代码包装在一个未命名的函数中:

    func() {
        //read the file or folder handle inside zip
        fileOpenHandle, err := fileReadHandler.Open()
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        defer fileOpenHandle.Close()
        targetUnZipPath := filepath.Join(tempWrkDir, fileReadHandler.Name)
        if fileReadHandler.FileInfo().IsDir() {
            os.MkdirAll(targetUnZipPath, fileReadHandler.Mode())
            //fmt.Println("Creating directory", path)
        } else {
            // create new dummy file to copy original file.
            newTempFileHandle, err := os.OpenFile(targetUnZipPath, os.O_WRONLY|os.O_CREATE, fileReadHandler.Mode())

            if err != nil {
                fmt.Println(err)
                os.Exit(1)
            }

            defer newTempFileHandle.Close()
            //copying original file to dummy file.
            if _, err = io.Copy(newTempFileHandle, fileOpenHandle); err != nil {
                fmt.Println(err)
                os.Exit(1)
            }
        }
    }()

然后您的延迟将在您尝试删除文件之前发生。不过,我建议将其提取到命名函数中。