filegodeferred-execution

Remove file on function failure


If I run this code:

package main
import "os"
func pass() bool { return false }

func main() {
   f, e := os.Create("file.txt")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   if ! pass() {
      e := os.Remove("file.txt")
      if e != nil {
         panic(e)
      }
   }
}

I get this result:

The process cannot access the file because it is being used by another process.

If I do this instead, I get expected result:

defer f.Close()
if ! pass() {
   f.Close()
   e := os.Remove("file.txt")
   if e != nil {
      panic(e)
   }
}

but I would like to avoid the duplicate Close() if possible. The file always needs to be closed, but also removed if some function fails. Is a better way available for what I am trying to do? To respond to comment: the file will be written to from multiple HTTP requests. It's possible first request could pass, and second request fail.


Solution

  • If this situation comes up frequently, then create a helper function:

    func nuke(f *os.File) {
       name := f.Name()
       f.Close()
       if err := os.Remove(name); err != nil {
          panic(err)
       }
    }
    

    Use it like this:

    func main() {
       f, e := os.Create("file.txt")
       if e != nil {
          panic(e)
       }
       defer f.Close()
       if ! pass() {
          nuke(f)
       }
    }