我正在构建这个程序,我在烧瓶网络应用程序上索引我的外部硬盘驱动器,可以在其中下载文件。在通过
flask.send_file()
下载文件夹之前,需要先将其存档,因为 Flask 无法仅发送目录文件。
所以我通过
shutil.make_archive()
创建存档,完成后开始下载。
这里的问题是,某些文件可能会变得非常大,即使 Shutil 可以处理它们,也可能需要一些时间才能完成归档,因为这是在旧的外部硬盘驱动器上。
幸运的是,当 Shutil 开始创建存档时,它是可见的,因此可能会有一些用处。
这里是处理 zip 文件下载和创建的 javascript。这按预期工作:
async function download_file() {
var download_path;
if (!(path.includes('.'))) {
const promise = await fetch(`/archive?path=${path}&name=${select}`, {method: 'GET'});
download_path = await promise.json();
} else {
download_path = path;
}
var downloader_a = document.createElement('a');
downloader_a.href = `/download?path=${download_path}`;
downloader_a.click();
}
蟒蛇陪伴:
@app.route('/download')
def download():
path = request.args.get('path')
return send_file(drive + path, as_attachment=True)
@app.route('/archive')
def archive_folder():
path = drive + request.args.get('path')
name = request.args.get('name')
shutil.make_archive('{}{}/{}'.format(drive, archiving_folder, name), 'zip', path)
return jsonify('{}/{}.zip'.format(archiving_folder, name))
所以我相信这个问题是由于我的 javascript 函数的异步特性而产生的。我尝试的是从创建存档的 JavaScript 中删除
await
,以便它从此开始:
const promise = await fetch(`/archive?path=${path}&name=${select}`, {method: 'GET'});
download_path = await promise.json();
对此:
const promise = fetch(`/archive?path=${path}&name=${select}`, {method: 'GET'});
download_path = promise.json();
我认为这可能不太可能,因为当我这样做时,会下载不完整的存档,但我想在存档生成时下载它。有什么想法吗?
提前致谢。
通过使用评论中推荐的资源dave,我能够精确地实现我正在寻找的内容。
安装 zipstream-ng 并完成示例后,我将 javascript 下载功能更改为:
async function download_file() {
var downloader_a;
downloader_a = document.createElement('a');
if (!(path.includes('.'))) {
downloader_a.href = `/zip_stream?path=${path}&name=${selected_item}`
} else {
downloader_a.href = `/download?path=${path}`;
}
downloader_a.click();
对应的python:
from zipstream import ZipStream, ZIP_DEFLATED
@app.route('/zip_stream')
def stream_zip_file():
path = drive + request.args.get('path')
name = request.args.get('name')
zs = ZipStream.from_path(path)
return Response(
zs,
mimetype='application/zip',
headers={
"Content-Disposition": f"attachment; filename={name}.zip",
"Content-Length": len(zs),
"Last-Modified": zs.last_modified,
}
)
现在,当下载文件夹时,将传输该文件夹的 zip 文件。