2017-01-02 39 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(路徑)** –

相關問題