如何在程序退出时使用golang删除文件? [英] How to delete a file using golang on program exit?

查看:190
本文介绍了如何在程序退出时使用golang删除文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  func main(){
//标志指定我们是上传文件夹还是单个文件
压缩:= flag.Bool(z,false,用于压缩文件夹并将它们作为服务器上的单个文件提供(当服务器关闭时删除压缩文件。 b $ b save:= flag.Bool(s,false,即使在服务器关闭后也使用-z保存压缩文件。)
flag.Parse()


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

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

if!(* save){
//我希望当我在cmd $ b上按ctrl + c时删除文件$ b defer os.Remove(flag.Args()[0])
}
}
http.HandleFunc(/,ShareFile)
fmt.Printf(Sharing文件在%s:8080 \ n,GetOutboundIP())

log.Fatal(http.ListenAndServe(:8080,nil))
}其他{
fmt.Println(无效的用法。没有提到文件。 )
}

}

当我点击ctrl-c时,程序退出并且main函数关闭,因此不应该os.Remove(xyz)得到执行?一段旅程说,defer在函数返回时执行表达式,在这里,我不觉得main得到oppurtunity来返回任何东西。



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

已经在评论中得到了回复,但我会在此处记录完整性。



defer 只适用于程序和你使用它的代码贯穿其中另一方面,通过命令停止程序或将其杀死,另一方面向程序发送一个信号,然后异常终止,这不会让程序运行所有 defer

如果你想清理OS终止,你可以监听OS信号 - 基于这里的例子

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

main ,它会保持一个goroutine在程序生命周期中监听OS信号。需要编写 cleanupAllTheThings()函数以尽可能快地运行而不会阻塞生效 - 您永远不知道操作系统什么时候会以偏见终止您。 / p>

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


I have made a command line application where I am zipping up folders and sharing on my local server for others to download. What I want to do is delete my copy of the zipped folder as soon as I close the server. This is my code:

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

}

When I hit ctrl-c, the program exits and main function closes and as a result,shouldn't os.Remove(xyz) get executed? A tour of go says, defer executes the expression when the function returns. Here, I don't feel main gets the oppurtunity to return anything at all.

What is a workaround to achieve what I am trying to do? I have some solutions in my head like wait for a keypress etc. but I want this program to be super simple,so is there a way to delete the file as soon as the server closes/program exits without requiring any further input from me?

解决方案

This has already been answered in the comments, but I'll document it here for completeness.

defer works only when the program and code you're using it in runs through its course normally. Stopping a program with with a command or killing it, on the other hand, sends a signal to the program and then terminates it abnormally, which does not allow the program to run all the defer statements cleanly.

If you want to cleanup on OS termination, you can listen for OS signals - code based on the example here:

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

If you call this from main, it will keep a goroutine running for the life of your program listening to the OS signals. And the cleanupAllTheThings() function needs to be written to run as fast as possible without blocking to be effective - you never know when the OS is going to terminate you with prejudice.

Also, this will not protect you from someone pulling out the plug or a kernal panic - so it usually makes sense to have some kind cleanup of the old program state on startup or in a separate cleanup script.

这篇关于如何在程序退出时使用golang删除文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆