【问题标题】:GAE: Access blobstore content programmatically?GAE:以编程方式访问 blobstore 内容?
【发布时间】:2012-12-26 01:07:30
【问题描述】:

我的用例:我不使用 blobstore 上传和下载文件。我使用 blobstore 来存储我的程序正在创建的非常大的字符串。保留存储 blob 的路径后,我可以稍后再次加载字符串(请参阅documentation

我的问题:有没有更简单的方法来访问 blob 内容而无需存储路径? BlobstoreService 只允许我直接服务于 HttpServletReponse。

【问题讨论】:

  • 为什么不使用“文本”来存储大字符串?
  • 'Text' 只能存储 1MB (see api) 并且整个数据存储限制为 1MB (see api)

标签: java google-app-engine blobstore


【解决方案1】:

您只需要存储一个 BlobKey - 永远不需要存储路径(文件与否)。

要访问 blob 的内容:

BlobstoreService blobStoreService = BlobstoreServiceFactory.getBlobstoreService();
String myString =
   new String(blobStoreService.fetchData(blobKey, 0, BlobstoreService.MAX_BLOB_FETCH_SIZE-1);

编辑: 如果你有一个很长的字符串,你可以使用任何标准的方法来读取一个字节数组到一个字符串,方法是从一个循环中的 blob 中获取数据。

【讨论】:

  • 由于 MAX_BLOB_FETCH_SIZE=1015808 (see api),我是否必须在一个循环中获取所有 byte[]-parts,连接它们然后转换为 String?
  • 不需要循环。我提供的代码将一步获取整个字符串。将最后一个索引设置为大于实际字符串长度不会受到任何惩罚。
  • 如果我的字符串大于 1MB?
  • 然后您可以按照您在第一条评论中的建议循环访问该 blob。为此,您不需要 FileService - 您正在添加一个额外的、不必要的步骤。
  • 我进行了几次测试(~5MB Blob)。您的解决方案读取它们的速度比文件服务快 20 倍左右。谢谢! ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); for (int i = 0; i < blobInfo.getSize(); i += BlobstoreService.MAX_BLOB_FETCH_SIZE) {outputStream.write(blobStoreService.fetchData(blobInfo.getBlobKey(), i, i + BlobstoreService.MAX_BLOB_FETCH_SIZE - 1));} returnValue = outputStream.toString("UTF-8");
【解决方案2】:

我猜当您说“持久化存储 blob 的路径”时,您的意思是 BlobKey

FileService 允许您直接访问 blob 数据:

// Get a file service
FileService fileService = FileServiceFactory.getFileService();

// Get a file backed by blob
AppEngineFile file = fileService.getBlobFile(blobKey)

// get a read channel
FileReadChannel readChannel = fileService.openReadChannel(file, false);

// Since you store a String, I guess you want to read it a such
BufferedReader reader = new BufferedReader(Channels.newReader(readChannel, "UTF8"));
// Do this in loop unitil all data is read
String line = reader.readLine();

【讨论】:

  • 无需使用 FileService 从 BlobStore 获取字符串。可以直接使用 BlobstoreService 完成。
  • AppEngineFile file = fileService.getBlobFile(blobKey) 正是我想要的!与(new BlobInfoFactory()).queryBlobInfos() 一起,很容易围绕blobstore 构建一个小的put/get 包装器。谢谢
  • 顺便说一句:当我说“保持存储 blob 的路径”时,我的意思是路径。我正在做的是用path = file.getFullPath()保存并用AppEngineFile file = new AppEngineFile(path);加载。
  • 这不是最快的解决方案(见上文)!但以防万一有人需要代码:AppEngineFile file = fileService.getBlobFile(blobInfo.getBlobKey()); boolean lock = false; FileReadChannel readChannel = fileService.openReadChannel(file, lock); BufferedReader bufferedReader = new BufferedReader(Channels.newReader(readChannel, "UTF-8")); returnValue = bufferedReader.readLine(); bufferedReader.close(); readChannel.close();
猜你喜欢
  • 2014-01-06
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 2015-03-27
相关资源
最近更新 更多