How to check if a file exists in Go?

前端 未结 11 1790
陌清茗
陌清茗 2020-11-30 16:23

Go\'s standard library does not have a function solely intended to check if a file exists or not (like Python\'s os.path.exists). What is the idiomatic way

11条回答
  •  悲哀的现实
    2020-11-30 16:47

    As mentioned in other answers, it is possible to construct the required behaviour / errors from using different flags with os.OpenFile. In fact, os.Create is just a sensible-defaults shorthand for doing so:

    // Create creates or truncates the named file. If the file already exists,
    // it is truncated. If the file does not exist, it is created with mode 0666
    // (before umask). If successful, methods on the returned File can
    // be used for I/O; the associated file descriptor has mode O_RDWR.
    // If there is an error, it will be of type *PathError.
    func Create(name string) (*File, error) {
        return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
    }
    

    You should combine these flags yourself to get the behaviour you are interested in:

    // Flags to OpenFile wrapping those of the underlying system. Not all
    // flags may be implemented on a given system.
    const (
        // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
        O_RDONLY int = syscall.O_RDONLY // open the file read-only.
        O_WRONLY int = syscall.O_WRONLY // open the file write-only.
        O_RDWR   int = syscall.O_RDWR   // open the file read-write.
        // The remaining values may be or'ed in to control behavior.
        O_APPEND int = syscall.O_APPEND // append data to the file when writing.
        O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
        O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
        O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
        O_TRUNC  int = syscall.O_TRUNC  // truncate regular writable file when opened.
    )
    

    Depending on what you pick, you will get different errors.

    Here's an example where I wish to open a file for writing, but I will only truncate an existing file if the user has said that is OK:

    var f *os.File
    if truncateWhenExists {
        // O_TRUNC - truncate regular writable file when opened.
        if f, err = os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644); err != nil {
            log.Fatalln("failed to force-open file, err:", err)
        }
    } else {
        // O_EXCL - used with O_CREATE, file must not exist
        if f, err = os.OpenFile(filepath, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0644); err != nil {
            log.Fatalln("failed to open file, err:", err) 
       }
    }
    

提交回复
热议问题