Blobstore读取器无法读取大型图像。

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

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.

huangapple
  • 本文由 发表于 2014年5月22日 00:40:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/23789185.html
匿名

发表评论

匿名网友

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

确定