当前位置: 首页 > 知识库问答 >
问题:

使用Tornado将二进制文件流式传输到Google Storage

何正德
2023-03-14

我正试图通过我的服务器将一个二进制文件从客户端请求流到谷歌云存储。

我使用Tornado框架将数据从请求流到服务器,并使用Google Cloud Storage API将文件流到Google-upload_from_file方法。

我是Tornado的新手,我正在使用@stream_request_body装饰器,这样我就可以从请求中获取数据块,并将每个块上传到Google。

我试着打开一个类似文件的对象,我可以在将文件本身上传到谷歌的同时编写每一个块。

问题是,我不能上传‘文件’到谷歌之前,我开始写块到它。

如有任何协助,将不胜感激。

共有1个答案

韦叶秋
2023-03-14

使用Google的HTTP库进行此操作是很棘手的,因为它们是为同步使用而设计的。您需要将实际上传放到另一个线程上,以避免阻塞IOLOOP。您可以使用os.pipe在Tornado线程和upload线程之间进行通信(将管道的写入端包装在PipeIOStream中,将读取端包装在os.fdopen)。以下是一个未经测试的解决方案草图:

def prepare(self):
    r, w = os.pipe()
    self.write_pipe = tornado.iostream.PipeIOStream(w)
    # Create our "file-like object" for upload_from_file
    self.read_pipe = os.fdopen(r)
    # Create an event for the upload thread to communicate back
    # to tornado when it's done, and save a reference to our IOLoop.
    self.upload_done = tornado.locks.Event()
    self.io_loop = tornado.ioloop.IOLoop.current()
    # Consider using a tornado.locks.Semaphore to limit the number of
    # threads you can create.
    self.thread = threading.Thread(target=self.upload_file)
    self.thread.start()

def upload_file(self):
    google_client.upload_from_file(self.read_pipe)
    # tell the IOLoop thread we're finished
    self.io_loop.add_callback(self.upload_done.set)

async def data_received(self, chunk):
    await self.write_pipe.write(chunk)

async def put(self):  # or post()
    self.write_pipe.close()
    await self.upload_done.wait()
    self.thread.join()
    self.render("upload_done.html")

或者,您可以避免使用Google的同步库,而使用底层HTTP API和AsynchTTPClient完成所有操作。通过这种方式来整理身份验证是很棘手的,但您可以避免线程不匹配。这将涉及使用body_producer,如本文中所述

 类似资料:
  • 问题内容: 我有一个200MB的文件,想通过下载提供给用户。但是,由于我们希望用户仅下载一次此文件,因此我们这样做: 强制下载。但是,这意味着整个文件必须加载到内存中,这通常不起作用。我们如何以每块kb的速度将文件流式传输给他们? 问题答案: 尝试这样的事情

  • 问题内容: 通过使用Express with Node,我可以成功上传文件,并通过以下代码块将其传递到Azure存储。 这很好用,但是Express创建一个临时文件并首先存储图像,然后将其从文件上传到Azure。这似乎是该过程中效率低下和不必要的步骤,而我最终不得不管理临时文件目录的清理。 我应该能够使用Azure SDK中的方法将文件直接流式传输到Azure存储,但是我对Node或Express

  • 更新:为了将来的参考,亚马逊现在已经更新了询问时的文档。根据@Loren Segal在下面的评论:- 我们已经更正了最新预览版中的文档,以正确记录此参数。很抱歉搞砸了! 有人能帮我使用上传二进制文件吗?

  • 我试图从SQL数据库中获取一些数据,这时对我的Camel服务进行了REST调用。我可以以字节数组的形式获取数据,并将其设置为Camel的主体,然后将其作为原始字节返回给调用者(web浏览器、应用程序等)。 我现在想用流来做这件事,而不是保存内存中的所有字节。如果我使用,当方法完成时,我可以从结果集获得的连接和流都将关闭,即使我试图返回一个并将其设置为主体。这阻止了我从DB直接流式传输数据,通过Ca

  • 问题内容: 我正在使用Jersey来实现RESTful API,该API主要是检索和提供JSON编码的数据。但是在某些情况下,我需要完成以下任务: 导出可下载的文档,例如PDF,XLS,ZIP或其他二进制文件。 检索多部分数据,例如一些JSON以及上载的XLS文件 我有一个基于页面的基于JQuery的Web客户端,该客户端创建对此Web服务的AJAX调用。目前,它不进行表单提交,而是使用GET和P

  • 下面是一个上传二进制文件的例子,WebService类的代码如下: package service; import java.io.InputStream; import java.io.OutputStream; import java.io.FileOutputStream; import javax.activation.DataHandler; public class