如何在程序退出时使用golang删除文件?

17

我制作了一个命令行应用程序,可以将文件夹压缩并共享到本地服务器上供他人下载。我想做的是,在关闭服务器时立即删除我的压缩文件夹副本。这是我的代码:

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说,defer在函数返回时执行表达式。在这里,我感觉主函数根本没有机会返回任何东西。
有什么解决方法可以实现我想做的事情吗?我脑海中有一些解决方案,比如等待按键等,但我希望这个程序非常简单,所以有没有一种方法可以在服务器关闭/程序退出时立即删除文件,而无需我进一步输入?

2
main 函数被中断,因此您需要安装一个信号处理程序并在该函数内调用 Remove - squiguy
让我看看信号处理程序是什么。谢谢你的回复。 - Krash
2
这是一个简单的例子:https://gobyexample.com/signals - squiguy
1
很酷,我猜我应该提到通道读取是阻塞的。 - squiguy
2
@Krash,你可能想考虑回答自己的问题,以便将来供其他人参考。 - squiguy
显示剩余6条评论
1个回答

23

这个问题在评论中已经有答案了,但是为了完整性,我会在这里记录一下。

defer只在程序和代码正常运行的情况下起作用。而停止一个程序或者使用命令杀死它,则会向程序发送信号并异常终止它,这将不允许程序干净地运行所有defer语句。

如果你想要在操作系统终止时进行清理工作,可以监听操作系统信号 - 代码参考 这个例子

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
  <- sigs
  cleanupAllTheThings()
  os.Exit(0)
}()
如果你从main函数中调用这个函数,它将在整个程序的生命周期中保持一个 goroutine 监听操作系统信号。并且cleanupAllTheThings() 函数需要尽可能快地运行而不阻塞,以便发挥最佳效果 - 你永远不知道操作系统什么时候会以偏见终止你的程序。
此外,这并不能保护你免受人为拔掉插头或内核恐慌的影响 - 因此通常有必要在启动时或单独的清理脚本中对旧程序状态进行某种清理。

5
提一下 - 实际删除文件的方法是 **os.Remove(path)**。 - Ivan Aracki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接