dpnof28482 2016-01-14 10:51
浏览 138
已采纳

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

I wrote code that unzips a file in a particular location then copies the contents of the folder to outside where the folder is unzipped then it removes the folder.

This is the Code I wrote:

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)
 }

The problem is that everything works fine except for deleting the folder. The folder has only one file in it. The location of the file is as follows:

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

The Location of the zip file is as follows:

 E:\go\copyDirectory\myfile.zip

The zip file has only one text file. The File inside the zip file is as follows:

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

The error I get is:

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

Thanks in advance.

  • 写回答

1条回答 默认 最新

  • douxing9641 2016-01-14 11:40
    关注

    You aren't closing the file. This:

    defer newTempFileHandle.Close()
    

    Is run when main finishes, which is after:

    err = RemoveContents("./myFiles")
    

    You can wrap that bit of code in an unnamed function:

        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)
                }
            }
        }()
    

    And then your defer will happen before you try and remove the files. I would recommend pulling this out into a named function though.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型