我在我的 Google App Engine 应用程序中使用 titan-files 为 Data Store 和 Blob Store 存储提供类似文件系统的层。我有一个 Google Apps 脚本,它向我的 Google App Engine 应用程序发送 POST 请求以将数据存储在 blob 存储中。它在发送 JSON 数据(作为字符串)时工作正常,但在发送二进制数据(如图像)时不起作用。
我最终尝试将 base64 编码数据作为字符串发送并将其存储在 blob 存储中。我认为我可以从 blob 存储中检索数据并对其进行 base64 解码以获得原始图像。但是,它似乎不起作用。
这是我用来从 Google Apps 脚本发送数据的代码:
function pushFileToFilePath(file, destinationFilePath) {
var payload =
{
"content" : Utilities.base64Encode(file.getAs("image/jpeg").getBytes())
};
var options =
{
"method" : "post",
"payload" : payload
};
var response = UrlFetchApp.fetch("https://myappname.appspot.com/_titan/file?path=" + destinationFilePath, options);
if (response.getResponseCode() == 201)
{
return true;
}
return false;
}
发送请求后,数据在 blob 存储中可用,其大小与我对文件进行 base64 编码的结果所期望的一致。但是,如果我使用 Google App Engine 仪表板从 blob 商店下载文件并使用 base64 解码它
openssl -d -in base_64_encoded_file.txt -out image.jpg
我得到一个零字节的 image.jpg 文件。
我还尝试了其他方法来设置有效负载对象。例如使用:
var payload =
{
"content" : file.getAs("image/jpeg").getBytes()
};
在 blob 存储中给出一个 18 字节的文件,其中包含字符串“[Ljava.lang.Object”。使用:
var payload =
{
"content" : file.getAs("image/jpeg")
};
我的 Google App Engine 日志中出现以下异常:
Bad request:
Traceback (most recent call last):
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/handlers.py", line 103, in post
content, blob=blob, mime_type=mime_type, meta=meta, **method_kwargs)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/files.py", line 408, in Write
content, blob = self._MaybeWriteToBlobstore(content, blob)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/files/files.py", line 341, in _MaybeWriteToBlobstore
blob = utils.WriteToBlobstore(content, old_blobinfo=old_blobinfo)
File "/base/data/home/apps/s~myappname/live-1.364814133265166345/titan/common/utils.py", line 277, in WriteToBlobstore
content_file = cStringIO.StringIO(content)
TypeError: expected read buffer, instance found
我尝试使用 BytesIO 流式传输内容,但我遇到了其他异常。
您知道我如何将图像(或更一般的二进制数据)发布到泰坦文件吗?
谢谢!
更新
我通过更改从中检索“内容”数据的方式解决了我的问题:
content = self.request.str_POST.get('content')
对此:
content = self.request.get('content')
并使用我的 Google Apps 脚本中的以下代码发送数据:
var payload =
{
"content" : file.getAs("image/jpeg")
};
也就是说,只需将“内容”设置为 Blob 实例。
我不知道为什么我一开始没有尝试这个:) 无论如何,titan-file 中的更改是一种 hack 而不是永久解决方案,所以我会尝试提出一个可以处理两者的可靠补丁二进制和非二进制数据并将其提交给项目。
谢谢!