dpzff20644 2017-01-02 19:15
浏览 201
已采纳

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

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
",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?

  • 写回答

1条回答 默认 最新

  • doxd96148 2017-01-04 03:58
    关注

    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.

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

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘