将Python中的str数据转换为文件对象

4
我正在将视频发布到Google Cloud Buckets,签名的PUT URL可以解决问题。但是,如果文件大小超过10MB,则无法正常工作,因此我找到了一个开源项目,可以让我完成这个任务,但它使用的是类似于文件的对象。
def read_in_chunks(file_object, chunk_size=65536):
while True:
    data = file_object.read(chunk_size)
    if not data:
        break
    yield data

def main(file, url):
content_name = str(file)
content_path = os.path.abspath(file)
content_size = os.stat(content_path).st_size

print content_name, content_path, content_size

f = open(content_path)

index = 0
offset = 0
headers = {}

for chunk in read_in_chunks(f):
    offset = index + len(chunk)
    headers['Content-Type'] = 'application/octet-stream'
    headers['Content-length'] = content_size
    headers['Content-Range'] = 'bytes %s-%s/%s' % (index, offset, content_size)
    index = offset
    try:
        r = requests.put(url, data=chunk, headers=headers)
        print "r: %s, Content-Range: %s" % (r, headers['Content-Range'])
    except Exception, e:
        print e

我上传视频的方式是通过传递json格式数据。
class GetData(webapp2.RequestHandler):
def post(self):
    data = self.request.get('file')

然后我所做的就是请求请求.put(url, data=data)。这个过程非常顺利。
我该如何将Python识别为str类型的数据转换为文件对象?
2个回答

16

所谓的“类文件”对象在大多数情况下只是实现了Python缓冲区接口的对象,也就是具有像readwriteseek等方法。

用于缓冲区接口工具的标准库模块称为io。根据你处理的数据类型,你需要使用io.StringIOio.BytesIO,如果你正在处理Unicode编码字符串,则应该使用io.StringIO,但你可能正在处理原始字节流(例如图像文件),而不仅仅是文本,因此io.BytesIO才是你要寻找的内容。当处理文件时,这与对Unicode文件执行open(path, 'r')和对字节进行原始处理执行open(path, 'rb')的区别相同。

这两个类都将文件类对象的数据作为第一个参数,所以你只需执行:

f = io.BytesIO(b'test data')

之后,f 将是一个对象,它的使用方式与文件相同,除了它将数据保存在内存中而不是磁盘上。


谢谢,这就是解决方案。现在我只需要弄清楚为什么我收到了400的响应。但是非常感谢,这正是我在寻找的。 - Adrian Humphrey

1
使用 StringIO
data= StringIO(data)
read_in_chunks(data)

2
这个解决方案在Python 3下不起作用,你需要使用io模块。请查看我的答案获取更多细节。 - Underyx
@Underyx... OP 似乎正在使用 Python2! - Iron Fist
1
@IronFist 是的,这真是遗憾。无论如何,这个问题可能不仅仅被Python 2用户发现,所以重要的是要注意其中一个答案与两个版本都兼容,而另一个则不兼容。 - Underyx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接