【问题标题】:Boto "get byte range" returns more than expectedBoto“获取字节范围”返回超出预期
【发布时间】:2013-05-28 18:01:42
【问题描述】:

这是我在这里的第一个问题,因为我对这个世界还很陌生!我花了几天时间试图自己解决这个问题,但到目前为止还没有找到任何有用的信息。

我正在尝试从存储在 S3 中的文件中检索字节范围,使用类似:

S3Key.get_contents_to_file(tempfile, headers={'Range': 'bytes=0-100000'}

我试图从中恢复的文件是一个视频文件,特别是一个 MXF。当我请求一个字节范围时,我在临时文件中得到的信息比请求的信息多。例如,使用一个文件,我请求 100,000 字节并返回 100,451。

关于 MXF 文件需要注意的一点是,它们合法地包含 0x0A(ASCII 换行)和 0x0D(ASCII 回车)。

我进行了一番挖掘,似乎只要文件中存在 0D 字节,检索到的信息就会添加 0A 0D 而不仅仅是 0D,因此似乎检索到的信息比需要的信息多。

例如,原始文件包含以下十六进制字符串:

02 03 00 00 00 00 3B 0A 06 0E 2B 34 01 01 01 05

但是从 S3 下载的文件有:

02 03 00 00 00 00 3B 0D 0A 06 0E 2B 34 01 01 01 05

我尝试调试代码并通过 Boto 逻辑工作,但我在这方面相对较新,所以很容易迷路。

我创建这个是为了测试,它显示了问题

from boto.s3.connection import S3Connection
from boto.s3.connection import Location
from boto.s3.key import Key
import boto
import os


## AWS credentials
AWS_ACCESS_KEY_ID = 'secret key'
AWS_SECRET_ACCESS_KEY = 'access key'

## Bucket name and path to file
bucketName = 'bucket name'
filePath = 'path/to/file.mxf'

#Local temp file to download to
tempFilePath = 'c:/tmp/tempfile'


## Setup the S3 connection and create a Key to access the file specified
## in filePath
conn = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
bucket = conn.get_bucket(bucketName)
S3Key = Key(bucket)
S3Key.key = filePath

def testRangeGet(bytesToRead=100000): # default read of 100K
    tempfile = open(tempFilePath, 'w')
    rangeString = 'bytes=0-' + str(bytesToRead -1)  #create byte range as string
    rangeDict = {'Range': rangeString} # add this to the dictionary
    S3Key.get_contents_to_file(tempfile, headers=rangeDict) # using Boto
    tempfile.close()
    bytesRead = os.path.getsize(tempFilePath)
    print 'Bytes requested = ' + str(bytesToRead)
    print 'Bytes recieved = ' + str(bytesRead)
    print 'Additional bytes = ' + str(bytesRead - bytesToRead)

我猜 Boto 代码中有一些东西正在寻找某些 ASCII 转义字符并对其进行修改,但我找不到任何方法来指定仅将其视为二进制文件。

有没有人遇到过类似的问题,可以分享一下解决方法?

谢谢

提姆

【问题讨论】:

  • 您使用的是哪个 boto 版本? boto.__version__
  • 使用boto 2.6.0版
  • 尝试了其他方法,只是为了确保它与 {'Range' : 'bytes=0-100000'} 位没有直接关系,因此使用 get_contents_as_file 下载了整个文件并且: Bytes requested =收到的 234630656 字节 = 235363424 额外字节 = 732768
  • 我从未遇到过使用相同版本的 boto 访问 S3 的问题。但我也从未使用过 Windows 来执行此操作(但您似乎从您的临时文件路径中假设)。可能是 Windows 问题?
  • 我使用key.get_contents_as_string() 仅用于访问数据。也许这也适合你?

标签: python amazon-s3 range boto


【解决方案1】:

将您的输出文件作为二进制文件打开。否则写入该文件会自动将 LF 转换为 CR/LF。

tempfile = open(tempFilePath, 'wb')

这当然只在 Windows 系统上是必需的。 Unix 不会转换任何内容,无论文件是作为文本文件还是二进制文件打开。

您在上传时也应该小心,不要一开始就将此类损坏的数据输入 S3。

【讨论】:

  • 感谢 Alfe,有人指出这一点很简单明了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多