英文:
Blobstore reader won't read large images
问题
我正在尝试从Go服务器端代码中的Blobstore读取图像。但是,如果图像很大(例如:0.5MB - 1.7MB),字节缓冲区的大部分内容会变为0,从而导致图像损坏。
如果我使用serveUrl,图像可以正常工作,但在这种情况下这不是一个选项。
我最初的想法是读取有大小限制,在这里找到了相关信息:
> 除了系统范围的安全配额外,还有一个特定于Blobstore的限制:应用程序使用API调用一次可以读取的Blobstore数据的最大大小为32兆字节。
我读取的图像远远没有达到32MB。
我使用以下函数从Blobstore中读取:
func BlobAsBase64(c appengine.Context, blobKey string) (*blobstore.BlobInfo, string, error) {
info, err := blobstore.Stat(c, appengine.BlobKey(blobKey))
if err != nil {
return nil, "", err
}
imageBuffer := make([]byte, info.Size)
reader := blobstore.NewReader(c, appengine.BlobKey(blobKey))
if _, err = reader.Read(imageBuffer); err != nil {
return nil, "", err
}
imageBase64 := base64.StdEncoding.EncodeToString(imageBuffer)
return info, imageBase64, nil
}
为什么我从Blobstore中读取图像时会导致图像损坏?
英文:
I am trying to read images from the Blobstore from the Go server side code. But if the image is large (as in: 0.5MB - 1.7MB) a large portion of the byte buffer becomes 0 which breaks the image.
The image works if I use serveUrl, but this is not an option for me in this case.
My first thought was that there was a size limit to the read, found this:
> In addition to systemwide safety quotas, a limit applies specifically
> to the use of the Blobstore: the maximum size of Blobstore data that
> can be read by the application with one API call is 32 megabytes.
The images I read are nowhere near 32MB.
Function I use to read from the Blobstore:
func BlobAsBase64(c appengine.Context, blobKey string) (*blobstore.BlobInfo, string, error) {
info, err := blobstore.Stat(c, appengine.BlobKey(blobKey))
if err != nil {
return nil, "", err
}
imageBuffer := make([]byte, info.Size)
reader := blobstore.NewReader(c, appengine.BlobKey(blobKey))
if _, err = reader.Read(imageBuffer); err != nil {
return nil, "", err
}
imageBase64 := base64.StdEncoding.EncodeToString(imageBuffer)
return info, imageBase64, nil
}
What is the reason that my images become broken when I read them from the Blobstore?
答案1
得分: 2
我猜测这个不起作用的原因是因为reader.Read
方法在填充缓冲区之前就返回了。请参考io.Reader的合同:
Read将最多len(p)个字节读入p。它返回读取的字节数(0 <= n <= len(p))和遇到的任何错误。即使Read返回n < len(p),在调用期间它也可能使用p的所有空间作为临时空间。如果有一些数据可用但不足len(p)个字节,Read通常会返回可用的数据而不是等待更多数据。
特别注意最后一句话。
尝试使用ioutil.ReadAll而不是reader.Read(imageBuffer)
,这应该可以解决你的问题。
英文:
I conjecture the reason this isn't working is because the reader.Read
method is returning before it has filled the buffer. See the contract for io.Reader
> Read reads up to len(p) bytes into p. It returns the number of bytes
> read (0 <= n <= len(p)) and any error encountered. Even if Read
> returns n < len(p), it may use all of p as scratch space during the
> call. If some data is available but not len(p) bytes, Read
> conventionally returns what is available instead of waiting for more.
Note the last sentence in particular.
Instead of reader.Read(imageBuffer)
try using ioutil.ReadAll which should fix your problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论