2017-01-02 113 views
3

我制作了一个命令行应用程序,用于在其中压缩文件夹并在本地服务器上共享以供其他人下载。我想要做的就是关闭服务器后立即删除我的压缩文件夹副本。这是我的代码:如何在程序退出时使用golang删除文件?

func main() { 
    //flag to specify whether we will be uploading folder or a single file 
    zipped := flag.Bool("z",false,"Use for zipping folders and serving them as a single file on the server.(Deletes the zipped file once the server closes.)") 
    save := flag.Bool("s",false,"Use with -z for saving the zipped files locally even after the server closes.") 
    flag.Parse() 


    if len(flag.Args())>0{ 

     if *zipped{ 
      fmt.Println("zipping...") 
      flag.Args()[0]=ZipFile() 

      if !(*save){ 
       //I expect this to remove the file when I hit ctrl+c on cmd 
       defer os.Remove(flag.Args()[0]) 
       } 
     } 
     http.HandleFunc("/",ShareFile) 
     fmt.Printf("Sharing file on %s:8080\n",GetOutboundIP()) 

     log.Fatal(http.ListenAndServe(":8080",nil)) 
    }else{ 
     fmt.Println("Invalid usage. No file mentioned. Use wshare -h for help.") 
    } 

} 

当我打CTRL-C,退出程序和主要功能关闭,因此,不应该os.Remove(XYZ)得到执行? A tour of go表示,函数返回时,延迟执行表达式。在这里,我并不觉得主要的机会会返回任何东西。

什么是解决方法来实现我想要做的事情?我的头脑中有一些解决方案,比如等待按键等等,但是我希望这个程序变得非常简单,所以当服务器关闭/程序退出时,有没有办法删除文件,而不需要我进一步的输入?

+2

'main'函数被中断,因此您需要安装一个信号处理程序并在该函数内调用'Remove'。 – squiguy

+0

让我看看信号处理程序是什么。感谢您的回应。 – Krash

+2

以下是一个简单的示例:https://gobyexample.com/signals – squiguy

回答

4

这已在评论中得到解答,但为了完整性我将在此处记录它。

defer仅当您正在使用的程序和代码正常运行时才有效。另一方面,使用命令停止程序或将其杀死,则会向程序发送一个信号,然后异常终止,这不会让程序干净地运行所有的defer语句。

如果你想在OS终止清理,你可以听的OS信号 - 基于the example here代码:

sigs := make(chan os.Signal, 1) 
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 
go func() { 
    <- sigs 
    cleanupAllTheThings() 
    os.Exit(0) 
}() 

如果从main调用此方法,它会保持一个够程运行的寿命你程序监听操作系统信号。并且需要写入cleanupAllTheThings()函数以尽可能快地运行,而不会阻塞生效 - 您永远不知道操作系统什么时候会以偏见终止您。

此外,这不会保护你免受拔出插头或内核恐慌的人 - 因此在启动时或在单独的清理脚本中对旧程序状态进行某种清理通常是有意义的。

+0

只是提及 - 实际删除文件将是** os.Remove(路径)** –

相关问题