我正在 appengine 中开发一个应用程序,我们希望能够使内容可供离线用户使用。这意味着我们需要获取所有使用过的 blobstore 文件并将它们保存以供离线用户使用。我正在使用服务器端来执行此操作,因此它只执行一次,而不是针对每个最终用户。我正在使用任务队列来运行这个过程,因为它很容易超时。假设所有这些代码都作为任务运行。
小型集合可以正常工作,但较大的集合会导致 appengine 错误 202,并且它会一次又一次地重新启动任务。以下是结合将 Zip 文件写入 GAE Blobstore并遵循Google Appengine JAVA中有关大型 zip 文件的建议的示例代码 -通过根据需要重新打开频道来压缩保存在 Blobstore 中的大量图像。还引用了AppEngine 错误代码 202 - 任务队列作为错误。
//Set up the zip file that will be saved to the blobstore
AppEngineFile assetFile = fileService.createNewBlobFile("application/zip", assetsZipName);
FileWriteChannel writeChannel = fileService.openWriteChannel(assetFile, true);
ZipOutputStream assetsZip = new ZipOutputStream(new BufferedOutputStream(Channels.newOutputStream(writeChannel)));
HashSet<String> blobsEntries = getAllBlobEntries(); //gets blobs that I need
saveBlobAssetsToZip(blobsEntries);
writeChannel.closeFinally();
......
private void saveBlobAssetsToZip(blobsEntries) throws IOException {
for (String blobId : blobsEntries) {
/*gets the blobstote key that will result in the blobstore entry - ignore the bsmd as
that is internal to our wrapper for blobstore.*/
BlobKey blobKey = new BlobKey(bsmd.getBlobId());
//gets the blob file as a byte array
byte[] blobData = blobstoreService.fetchData(blobKey, 0, BlobstoreService.MAX_BLOB_FETCH_SIZE-1);
String extension = type of file saved from our metadata (ie .jpg, .png, .pfd)
assetsZip.putNextEntry(new ZipEntry(blobId + "." + extension));
assetsZip.write(blobData);
assetsZip.closeEntry();
assetsZip.flush();
/*I have found that if I don't close the channel and reopen it, I can get a IO exception
because the files in the blobstore are too large, thus the write a file and then close and reopen*/
assetsZip.close();
writeChannel.close();
String assetsPath = assetFile.getFullPath();
assetFile = new AppEngineFile(assetsPath);
writeChannel = fileService.openWriteChannel(assetFile, true);
assetsZip = new ZipOutputStream(new BufferedOutputStream(Channels.newOutputStream(writeChannel)));
}
}
让它在 appengine 上运行的正确方法是什么?再次,小型项目工作正常并 zip 保存,但具有更多 blob 文件的大型项目会导致此错误。