- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试允许 python 应用程序访问存储在 S3 中的多 GB 文件中的各个位置。我想创建一个类似文件的插入式替换对象,它可以在单独的线程中智能地从 S3 下载数据 block 以满足 seek() 和 read() 请求。
是否有一种简单的数据结构可用于存储文件的任意间隔?
它必须支持 O(log n) 查找和 O(n) 插入(n= block 数,而不是文件大小)。它还需要支持快速查询间隙,以便加载线程可以有效地找到它应该下载的下一个 block 。目前不支持 SortedCollection 之类的东西,建议我可能需要在新容器中手动使用 bisect_*。
示例用法是:
import os
import time
from bigfile import BigFile
chunksize = (2**20)*64 # 64MB
bf = BigFile('my_bucket', 'key_name', chunksize=chunksize)
# read from beginning (blocks until first chunk arrives)
bf.read(100)
# continues downloading subsequent chunks in background
time.sleep(10)
# seek into second chunk and read (should not block)
bf.seek(blocksize, os.SEEK_SET)
bf.read(100)
# seek far into the file
bf.seek(blocksize*100 + 54, os.SEEK_SET) # triggers chunk download starting at new location
bf.read(100) # blocks until chunk arrives
# seek back to beginning (should not block, already have this chunk)
bf.seek(0, os.SEEK_SET)
bf.read(100)
# read entire rest of file (blocks until all chunks are downloaded)
bf.read()
最佳答案
此实现使用固定大小和偏移量的 block 。如果 block 非常大并且网络非常慢,读取可能会阻塞很长时间(考虑从 block 的最后一个字节开始的读取,它必须等待整个前一个 block 加载,然后是下一个 block ).
理想情况下,我们可以使用任意大小和位置的 block ,因此我们可以优化加载以准确地从读取点开始。但下面是一个很好的 80% 解决方案。
import boto
import threading
import tempfile
import os
DEFAULT_CHUNK_SIZE = 2**20 * 64 # 64 MB per request
class BigFile(object):
def __init__(self, file_obj, file_size, chunksize=DEFAULT_CHUNK_SIZE, start=True):
self._file_obj = file_obj
self._file_size = file_size
self._lock = threading.RLock()
self._load_condition = threading.Condition(self._lock)
self._load_run = True
self._loc = 0
self._chunk_size = chunksize
chunk_count = self._file_size // self._chunk_size
chunk_count += 1 if self._file_size % self._chunk_size else 0
self._chunks = [None for _ in xrange(chunk_count)]
self._load_thread = threading.Thread(target=self._load)
if start:
self._load_thread.start()
def _chunk_loc(self):
' Returns (chunk_num, chunk_offset) for a given location in the larger file '
return self._loc // self._chunk_size, self._loc % self._chunk_size
def _load_chunk(self, chunk_num):
tf = tempfile.TemporaryFile()
start_idx = chunk_num * self._chunk_size
self._file_obj.seek(start_idx)
tf.write(self._file_obj.read(self._chunk_size))
with self._lock:
self._chunks[chunk_num] = (tf, tf.tell()) # (tempfile, size)
self._load_condition.notify()
def _load(self):
while self._load_run:
# check current chunk, load if needed
with self._lock:
chunk_num, _ = self._chunk_loc()
chunk_and_size = self._chunks[chunk_num]
if chunk_and_size is None:
self._load_chunk(chunk_num)
# find next empty chunk
for i in xrange(len(self._chunks)):
cur_chunk = chunk_num + i
cur_chunk %= len(self._chunks) # loop around
if self._chunks[cur_chunk] is None:
self._load_chunk(cur_chunk)
break
else:
# all done, stop thread
break
def seek(self, loc, rel=os.SEEK_SET):
with self._lock:
if rel == os.SEEK_CUR:
self._loc += loc
elif rel == os.SEEK_SET:
self._loc = loc
elif rel == os.SEEK_END:
self._loc = self._file_size + loc
def read(self, bytes_to_read):
ret = []
with self._lock:
chunk_num, chunk_offset = self._chunk_loc()
while (bytes_to_read > 0 or bytes_to_read == -1) and chunk_num < len(self._chunks):
while not self._chunks[chunk_num]:
self._load_condition.wait()
chunk, size = self._chunks[chunk_num]
cur_chunk_bytes = min(self._chunk_size-chunk_offset, bytes_to_read, size)
chunk.seek(chunk_offset, os.SEEK_SET)
data = chunk.read(cur_chunk_bytes)
ret.append(data)
bytes_to_read -= len(data)
chunk_num += 1
return ''.join(ret)
def start(self):
self._load_thread.start()
def join(self):
self._load_thread.join()
def stop(self):
self._load_run = False
class S3RangeReader:
def __init__(self, key_obj):
self._key_obj = key_obj
self.size = self._key_obj.size
self._pos = 0
def __len__(self):
return self.size
def seek(self, pos, rel=os.SEEK_SET):
if rel == os.SEEK_CUR:
self._pos += pos
elif rel == os.SEEK_SET:
self._pos = pos
elif rel == os.SEEK_END:
self._pos = self.size + pos
def read(self, bytes=-1):
if bytes == 0 or self._pos >= self.size:
return ''
else:
if bytes == -1:
bytes = self.size
headers = {'Range': 'bytes=%s-%s' % (self._pos, self._pos + bytes - 1)} # S3 ranges are closed ranges: [start,end]
return self._key_obj.get_contents_as_string(headers=headers)
if __name__ == '__main__':
key = boto.s3_connect().get_bucket('mybucket').get_key('my_key')
reader = S3RangeReader(key)
bf = BigFile(reader, len(reader)) # download starts by default
bf.seek(1000000)
bf.read(100) # blocks
bf.seek(0)
bf.read(100) # should not block
关于python - 从 S3 下载透明背景文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9015067/
当我尝试通过我的 .exe 文件从 url 下载 .pdf 文件时出现以下错误。 The server committed a protocol violation. Section=Response
我是一家非营利组织的 G Suite 管理员,刚刚发现数据导出功能,这似乎是个人帐户的外卖。 导出文件已准备好,现在可以从 Google Cloud Platform Storage 中的存储桶下载。
导航 引言 总体思路 七牛云相关的配置文件 获取七牛云上传token 相关类定义 核心代码实现 获取七牛云图片下载链接 公开空
这不是后端编程问题。我只能修改标记或脚本(或文档本身)。我在这里问的原因是因为我对适当术语的所有搜索都不可避免地导致有关编程此功能的问题和解决方案。我不是试图通过编程来强制它;我必须找出此 PDF 行
您好,我已在 Google AdSense 中注册,我想使用适用于 iOS 的 SDK,但目前我找不到 SDK 下载链接。 我的申请已获批准。 任何人都知道如何下载这个sdk。 我使用这个链接来描述如
我需要为当前在 SourceForge 上的 github 项目提供二进制文件和文档。在那里,我可以为我需要的下载提供一个目录结构,因为我必须为大约 10 个不同的操作系统提供几个版本。 github
我从 Canvas 下载绘图时遇到问题。这是我的代码: function downloadCanvas(link, canvasId, filename) { link.href =
ASP.NET 项目 我将使用 Azure 进行存储。问题(要求): 在我的项目中,我让注册用户下载文件。但我不希望用户将此下载链接分享给未注册的人(例如:我给注册用户的下载链接只能在他们的计算机上下
我编写了一个servlet,用于检查http header ,但我不知道为什么当页面加载时,它会自动开始下载。 /* * To change this template, choose To
我正在尝试将下载添加到我的网络浏览器,但遇到的问题是获取您尝试下载的文件的名称。这是我的下载代码: engine.locationProperty().addListener(new ChangeLi
我正在尝试下载网站的 html: String encoding = "UTF-8"; HttpContext localContext = new BasicHttpContext();
我制作了一个带有“开始下载”按钮的框架,用于从网站下载 JAR。 问题是每当我点击开始下载按钮时,整个框架就会卡住,直到下载完成,然后就正常了。 我该如何解决这个问题? 这是单击按钮时执行的代码 p
我得到这段代码来实现一些东西,它可以帮助我从给定的 URL 下载文件。 -(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSes
我正在尝试创建一个 Controller 来使用流方法下载和上传文件,在我的例子中,所有文件都作为 Blob 保存在数据库中。我阅读了 Jboss Netty 的文档,但我认为这不是我的最佳解决方案。
下载并保存文件 let destination: DownloadRequest.DownloadFileDestination = { _, _ in // var fileURL = sel
使用 htaccess 我基本上试图禁止访问该页面,即 http://example.com , 但它仍然允许人们下载文件,如果他们有直接链接即 http://example.com/hi.zip .
我正在寻求将脚本与我的控制面板集成,并且由于我是新手脚本编写者而遇到问题。我想做的是用 1 个脚本下载一个文件并解压它。 示例: wget http://example.com/example.tar
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
这个问题在这里已经有了答案: Top techniques to avoid 'data scraping' from a website database (14 个答案) 关闭 5 年前。 我有
这个问题在这里已经有了答案: Reading and parsing email from Gmail using C#, C++ or Python (6 个答案) 关闭 7 年前。 我只是想,是
我是一名优秀的程序员,十分优秀!