【问题标题】:Fetching blob from Google Blobstore without knowing size before hand在事先不知道大小的情况下从 Google Blobstore 获取 blob
【发布时间】:2013-04-03 23:18:44
【问题描述】:

我需要以编程方式从 Blobstore 获取 Blob,但事先不知道大小。有人知道怎么做吗?

我尝试过使用

BlobstoreService blobStoreService = BlobstoreServiceFactory.getBlobstoreService();
byte[] picture = blobStoreService.fetchData(blobKey, 0, Integer.MAX_VALUE);

但我收到一个错误,因为(至少看起来)Integer.MAX_VALUE 太大了。

java.lang.IllegalArgumentException: Blob fetch size 2147483648 it larger than maximum size 1015808 bytes.
at com.google.appengine.api.blobstore.BlobstoreServiceImpl.fetchData(BlobstoreServiceImpl.java:250)

那么有人知道如何正确执行此操作吗?另外,如果您可以顺便告诉我,将相同的图像作为“jpeg”还是“png”放入 blobstore 更好?

【问题讨论】:

  • 这似乎并不重要,但您知道给定的限制是包容性的,因此Integer.MAX_VALUE 可能会失败。在这里并不重要。
  • 啊,谢谢。它们具有包容性。
  • 一个inclusive API,难以置信。我认为app-engine 没有被认真对待。

标签: google-app-engine blobstore gae-eclipse-plugin


【解决方案1】:

希望这会有所帮助,这是我一段时间以来一直这样做的方式:

        BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
        BlobKey blobKey = new BlobKey(KEY);

        // Start reading
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        long inxStart = 0;
        long inxEnd = 1024;
        boolean flag = false;

        do {
            try {
                byte[] b = blobstoreService.fetchData(blobKey,inxStart,inxEnd);
                out.write(b);

                if (b.length < 1024)
                    flag = true;

                inxStart = inxEnd + 1;
                inxEnd += 1025;

            } catch (Exception e) {
                flag = true;
            }

        } while (!flag);

        byte[] filebytes = out.toByteArray();

我以前用过:

BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(blobKey);
filesize = blobInfo.getSize();

获取大小,但由于某种原因,有时此信息为空。

也许这一切都可以给你一个想法。

【讨论】:

  • 谢谢!我会去实施,让你知道。 +1。
  • 非常感谢您的帮助。
  • 使用fetchData() 一次最多可以获取BlobstoreService.MAX_BLOB_FETCH_SIZE 字节。该常量定义为in the javadoc,但它对fetchData 的使用仅记录在in the Python doc
【解决方案2】:
def blob_fetch(blob_key):
  blob_info = blobstore.get(blob_key)
  total_size = blob_info.size
  unit_size = blobstore.MAX_BLOB_FETCH_SIZE
  pos = 0
  buf = cStringIO.StringIO()
  try:
    while pos < total_size:
      buf.write(blobstore.fetch_data(blob_key, pos, min(pos + unit_size - 1, total_size)))
      pos += unit_size
    return buf.getvalue()
  finally:
    buf.close()

MAX_BLOB_FETCH_SIZE 在文档中不明显。

【讨论】:

    【解决方案3】:

    在 Python 中:

    from google.appengine.ext.blobstore import BlobInfo
    from google.appengine.api import blobstore
    import cStringIO as StringIO
    
    blobinfo = BlobInfo.get(KEY)
    
    offset = 0
    accumulated_content = StringIO.StringIO()
    while True:
      fetched_content = blobstore.fetch_data(
          blobinfo.key(),
          offset,
          offset + blobstore.MAX_BLOB_FETCH_SIZE - 1)
      accumulated_content.write(fetched_content)
      if len(fetched_content) < blobstore.MAX_BLOB_FETCH_SIZE:
        break
      offset += blobstore.MAX_BLOB_FETCH_SIZE
    

    【讨论】:

    • Python API 的google.appengine.ext.blobstore 中的BlobReaderclassread 方法也可以(而不是while 循环)。
    猜你喜欢
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 2011-01-14
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    相关资源
    最近更新 更多