How can I tell if a file with this name exists?

huangapple go评论111阅读模式
英文:

How can I tell if a file with this name exists?

问题

在写入GCS文件之前,我想测试一下文件是否存在。然而,我从file.Stat中得到了一个错误,返回os.IsNotExist中的false,并且我在appengine/fileappengine中没有看到可以进行测试的导出错误。从App Engine中确定文件在GCS中不存在的最佳方法是什么?

也有可能我完全错误地进行了操作,还有其他方法可以确保我不会覆盖或追加到现有文件中。如果有的话,我也很想了解一下。

我的复现代码:

package main

import (
    "net/http"
    "fmt"
    
    "appengine"
    "appengine/file"
)

func init() {
    http.HandleFunc("/test", reproduceHandler)
}

func reproduceHandler(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    // 这里需要你自己的存储桶名称
    _, err := file.Stat(c, "/gs/my-bucket-name/my-file-name")
    fmt.Fprintln(w, err)
}

当我访问"/test"时,显示如下内容:

API错误100(文件:EXISTENCE_ERROR)
英文:

Before writing to a GCS file, I'd like to test if it exists. However, I get an error back from file.Stat that returns false in os.IsNotExist, and I don't see any exported errors in appengine/file or appengine that I can test against. What's the best way to ascertain that a file does not exist in GCS from App Engine?

It's possible that I'm doing this the entirely wrong way, too, and that there's some other way to make sure I'm not overwriting or appending to an existing file. If there is, I'd love to hear about that, too.

My reproducing code:

package main

import (
	"net/http"
	"fmt"
	
	"appengine"
	"appengine/file"
)

func init() {
	http.HandleFunc("/test", reproduceHandler)
}

func reproduceHandler(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
    // You'll need your own bucket name here
	_, err := file.Stat(c, "/gs/my-bucket-name/my-file-name")
	fmt.Fprintln(w, err)
}

This shows the following when I visit "/test":

API error 100 (file: EXISTENCE_ERROR)

答案1

得分: 1

请看一下appengine在文件上如何定义错误,链接如下:

https://code.google.com/p/appengine-go/source/browse/appengine_internal/files/file_service.pb.go

你可以根据文件中的枚举类型来确定错误类型:

FileServiceErrors_OK                                 FileServiceErrors_ErrorCode = 0
FileServiceErrors_API_TEMPORARILY_UNAVAILABLE        FileServiceErrors_ErrorCode = 1
FileServiceErrors_REQUEST_TOO_LARGE                  FileServiceErrors_ErrorCode = 3
FileServiceErrors_RESPONSE_TOO_LARGE                 FileServiceErrors_ErrorCode = 4
FileServiceErrors_INVALID_FILE_NAME                  FileServiceErrors_ErrorCode = 5
FileServiceErrors_OPERATION_NOT_SUPPORTED            FileServiceErrors_ErrorCode = 6
FileServiceErrors_IO_ERROR                           FileServiceErrors_ErrorCode = 7
FileServiceErrors_PERMISSION_DENIED                  FileServiceErrors_ErrorCode = 8
FileServiceErrors_WRONG_CONTENT_TYPE                 FileServiceErrors_ErrorCode = 9
FileServiceErrors_FILE_NOT_OPENED                    FileServiceErrors_ErrorCode = 10
FileServiceErrors_WRONG_OPEN_MODE                    FileServiceErrors_ErrorCode = 11
FileServiceErrors_EXCLUSIVE_LOCK_REQUIRED            FileServiceErrors_ErrorCode = 12
FileServiceErrors_FILE_TEMPORARILY_UNAVAILABLE       FileServiceErrors_ErrorCode = 13
FileServiceErrors_EXISTENCE_ERROR                    FileServiceErrors_ErrorCode = 100
FileServiceErrors_FINALIZATION_ERROR                 FileServiceErrors_ErrorCode = 101
FileServiceErrors_UNSUPPORTED_CONTENT_TYPE           FileServiceErrors_ErrorCode = 102
FileServiceErrors_READ_ONLY                          FileServiceErrors_ErrorCode = 103
FileServiceErrors_EXCLUSIVE_LOCK_FAILED              FileServiceErrors_ErrorCode = 104
FileServiceErrors_EXISTENCE_ERROR_METADATA_NOT_FOUND FileServiceErrors_ErrorCode = 105
FileServiceErrors_EXISTENCE_ERROR_METADATA_FOUND     FileServiceErrors_ErrorCode = 106
FileServiceErrors_EXISTENCE_ERROR_SHARDING_MISMATCH  FileServiceErrors_ErrorCode = 107
FileServiceErrors_FINALIZATION_IN_PROGRESS           FileServiceErrors_ErrorCode = 108
FileServiceErrors_EXISTENCE_ERROR_OBJECT_NOT_FOUND   FileServiceErrors_ErrorCode = 109
FileServiceErrors_EXISTENCE_ERROR_BUCKET_NOT_FOUND   FileServiceErrors_ErrorCode = 110
FileServiceErrors_SEQUENCE_KEY_OUT_OF_ORDER          FileServiceErrors_ErrorCode = 300
FileServiceErrors_OUT_OF_BOUNDS                      FileServiceErrors_ErrorCode = 500
FileServiceErrors_GLOBS_NOT_SUPPORTED                FileServiceErrors_ErrorCode = 600
FileServiceErrors_FILE_NAME_NOT_SPECIFIED            FileServiceErrors_ErrorCode = 701
FileServiceErrors_FILE_NAME_SPECIFIED                FileServiceErrors_ErrorCode = 702
FileServiceErrors_FILE_ALREADY_EXISTS                FileServiceErrors_ErrorCode = 703
FileServiceErrors_UNSUPPORTED_FILE_SYSTEM            FileServiceErrors_ErrorCode = 704
FileServiceErrors_INVALID_PARAMETER                  FileServiceErrors_ErrorCode = 705
FileServiceErrors_SHUFFLER_INTERNAL_ERROR            FileServiceErrors_ErrorCode = 800
FileServiceErrors_SHUFFLE_REQUEST_TOO_LARGE          FileServiceErrors_ErrorCode = 801
FileServiceErrors_DUPLICATE_SHUFFLE_NAME             FileServiceErrors_ErrorCode = 802
FileServiceErrors_SHUFFLE_NOT_AVAILABLE              FileServiceErrors_ErrorCode = 803
FileServiceErrors_SHUFFLER_TEMPORARILY_UNAVAILABLE   FileServiceErrors_ErrorCode = 900
FileServiceErrors_MAX_ERROR_CODE                     FileServiceErrors_ErrorCode = 9999

你得到的错误很可能是FileServiceErrors_ErrorCode类型(或指向该类型的指针),所以通过类型断言来检查和比较你想要区分的情况:

_, err := file.Stat(c, "/gs/my-bucket-name/my-file-name")

if apiErr, ok := err.(*appengine_internal.APIError); ok {
	if apiErr.Code == int32(files.FileServiceErrors_EXISTENCE_ERROR) && apiErr.Service == "file" {
		// 文件不存在
	}
}

别忘了导入以下包:

import "appengine_internal"
import "appengine_internal/files"
英文:

Take a look at how appengine defines errors on files, here:

https://code.google.com/p/appengine-go/source/browse/appengine_internal/files/file_service.pb.go

You should be able to discern the error type based on the enumeration top in the file:

FileServiceErrors_OK                                 FileServiceErrors_ErrorCode = 0
FileServiceErrors_API_TEMPORARILY_UNAVAILABLE        FileServiceErrors_ErrorCode = 1
FileServiceErrors_REQUEST_TOO_LARGE                  FileServiceErrors_ErrorCode = 3
FileServiceErrors_RESPONSE_TOO_LARGE                 FileServiceErrors_ErrorCode = 4
FileServiceErrors_INVALID_FILE_NAME                  FileServiceErrors_ErrorCode = 5
FileServiceErrors_OPERATION_NOT_SUPPORTED            FileServiceErrors_ErrorCode = 6
FileServiceErrors_IO_ERROR                           FileServiceErrors_ErrorCode = 7
FileServiceErrors_PERMISSION_DENIED                  FileServiceErrors_ErrorCode = 8
FileServiceErrors_WRONG_CONTENT_TYPE                 FileServiceErrors_ErrorCode = 9
FileServiceErrors_FILE_NOT_OPENED                    FileServiceErrors_ErrorCode = 10
FileServiceErrors_WRONG_OPEN_MODE                    FileServiceErrors_ErrorCode = 11
FileServiceErrors_EXCLUSIVE_LOCK_REQUIRED            FileServiceErrors_ErrorCode = 12
FileServiceErrors_FILE_TEMPORARILY_UNAVAILABLE       FileServiceErrors_ErrorCode = 13
FileServiceErrors_EXISTENCE_ERROR                    FileServiceErrors_ErrorCode = 100
FileServiceErrors_FINALIZATION_ERROR                 FileServiceErrors_ErrorCode = 101
FileServiceErrors_UNSUPPORTED_CONTENT_TYPE           FileServiceErrors_ErrorCode = 102
FileServiceErrors_READ_ONLY                          FileServiceErrors_ErrorCode = 103
FileServiceErrors_EXCLUSIVE_LOCK_FAILED              FileServiceErrors_ErrorCode = 104
FileServiceErrors_EXISTENCE_ERROR_METADATA_NOT_FOUND FileServiceErrors_ErrorCode = 105
FileServiceErrors_EXISTENCE_ERROR_METADATA_FOUND     FileServiceErrors_ErrorCode = 106
FileServiceErrors_EXISTENCE_ERROR_SHARDING_MISMATCH  FileServiceErrors_ErrorCode = 107
FileServiceErrors_FINALIZATION_IN_PROGRESS           FileServiceErrors_ErrorCode = 108
FileServiceErrors_EXISTENCE_ERROR_OBJECT_NOT_FOUND   FileServiceErrors_ErrorCode = 109
FileServiceErrors_EXISTENCE_ERROR_BUCKET_NOT_FOUND   FileServiceErrors_ErrorCode = 110
FileServiceErrors_SEQUENCE_KEY_OUT_OF_ORDER          FileServiceErrors_ErrorCode = 300
FileServiceErrors_OUT_OF_BOUNDS                      FileServiceErrors_ErrorCode = 500
FileServiceErrors_GLOBS_NOT_SUPPORTED                FileServiceErrors_ErrorCode = 600
FileServiceErrors_FILE_NAME_NOT_SPECIFIED            FileServiceErrors_ErrorCode = 701
FileServiceErrors_FILE_NAME_SPECIFIED                FileServiceErrors_ErrorCode = 702
FileServiceErrors_FILE_ALREADY_EXISTS                FileServiceErrors_ErrorCode = 703
FileServiceErrors_UNSUPPORTED_FILE_SYSTEM            FileServiceErrors_ErrorCode = 704
FileServiceErrors_INVALID_PARAMETER                  FileServiceErrors_ErrorCode = 705
FileServiceErrors_SHUFFLER_INTERNAL_ERROR            FileServiceErrors_ErrorCode = 800
FileServiceErrors_SHUFFLE_REQUEST_TOO_LARGE          FileServiceErrors_ErrorCode = 801
FileServiceErrors_DUPLICATE_SHUFFLE_NAME             FileServiceErrors_ErrorCode = 802
FileServiceErrors_SHUFFLE_NOT_AVAILABLE              FileServiceErrors_ErrorCode = 803
FileServiceErrors_SHUFFLER_TEMPORARILY_UNAVAILABLE   FileServiceErrors_ErrorCode = 900
FileServiceErrors_MAX_ERROR_CODE                     FileServiceErrors_ErrorCode = 9999

The error you're getting is most likely of type FileServiceErrors_ErrorCode (or pointer to that type), so check and compare for the cases you'd like to discern by using a type-assertion:

_, err := file.Stat(c, "/gs/my-bucket-name/my-file-name")

if apiErr, ok := err.(*appengine_internal.APIError); ok {
	if apiErr.Code == int32(files.FileServiceErrors_EXISTENCE_ERROR) && apiErr.Service == "file" {
		// file does not exist
	}
}

Don't forget to

import "appengine_internal"
import "appengine_internal/files"

huangapple
  • 本文由 发表于 2014年5月23日 08:02:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/23819000.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定