如何用python像windows下的hfs那样生成 folder.tar

59 views
Skip to first unread message

Chunlin Zhang

unread,
Dec 10, 2012, 10:37:37 PM12/10/12
to pyth...@googlegroups.com
windows下的hfs有个功能是页面右下角有个 http://host/~folder.tar?recursive 的链接,点击以后会把当前页面浏览的目录整个打包成.tar文件下载,即使文件很大也是点击以后马上可以下载的,所以我想它应该是没有实际生成这个folder.tar文件,而是边读边生成

我用uliweb开发web应用的时候想做个类似的功能,想对一个文件夹打包生成tar文件提供给http下载,如果文件夹内容很大的话,我也想像hfs这样不生成文件来做

但是看了python里的tarfile模块感觉没啥概念,可能要去研究一下tar文件的格式?

大家有啥想法给支支招,谢谢!

CHUN ZHANG

unread,
Dec 10, 2012, 10:54:41 PM12/10/12
to pyth...@googlegroups.com
直接跑个shell命令?tar -czf file_or_dir ./xxx.tar.gz




--
--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
发言: pyth...@googlegroups.com
退订: python-cn+...@googlegroups.com (向此发空信即退!)
详情: http://code.google.com/p/cpyug/wiki/CpyUg
G+: https://plus.google.com/u/0/communities/108786798869709602787
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
 
 

yegle

unread,
Dec 10, 2012, 10:56:13 PM12/10/12
to pyth...@googlegroups.com
这要做streaming了吧…

读一段,gzip一下,yield丢给werkzeug

或者,异步进程gzip,生成一段yield一段

Chunlin Zhang

unread,
Dec 10, 2012, 10:57:00 PM12/10/12
to python-cn`CPyUG`华蟒用户组
那就生成了实际的文件了,看来还是要去了解一下tar文件的格式


2012/12/11 CHUN ZHANG <ma...@zhang-chun.org>

yegle

unread,
Dec 10, 2012, 11:01:03 PM12/10/12
to pyth...@googlegroups.com
不生成实际文件,万一中途中断下载就要重新打包了。

Chunlin Zhang

unread,
Dec 10, 2012, 11:37:32 PM12/10/12
to python-cn`CPyUG`华蟒用户组



2012/12/11 yegle <cny...@gmail.com>
不生成实际文件,万一中途中断下载就要重新打包了。
那就重新生成数据好了,因为是 .tar,完全不压缩的,所以没有多做什么事情
我之前用hfs传过>3G的文件打包,如果要生成文件肯定要等很久,但hfs却是马上就能下载的

est

unread,
Dec 11, 2012, 12:05:52 AM12/11/12
to pyth...@googlegroups.com
http://www.v2ex.com/t/54031

这里有个.NET实现。。。


2012/12/11 Chunlin Zhang <zhangc...@gmail.com>

--

Shuai Lin

unread,
Dec 11, 2012, 1:12:55 AM12/11/12
to pyth...@googlegroups.com
上个月刚好做了把目录打包成 zip 下载的工作, 下面是当时的一些调研结果, 如果有错, 请大家指出
-----------------------------

要打包下载, 有两种做法:

1. 简单做法

收到客户端请求后, 先在服务器端打包,生成一个临时文件,然后把这个文件返回给客户端

2. 复杂做法 (streaming)

即边压缩边返回, 这样做要考虑的有

i) 但由于无法在一开始压缩时就知道整个压缩包最后的大小是多少。 因此没法设置 content length 这个字段, 只能通过的 HTTP header 的  tranfer-encoding 字段为 chunked , 关于这个可以看 wikipedia 上的解释

ii) 框架支持。 一般的 web 框架, 比如 django, 都是希望调用一次你的请求处理函数, 你的函数直接返回一个完整的响应。 而 streaming 这种方式需要你边压缩边写, 分多次才能写完整个响应

iii) 库支持。 一般的压缩库的使用方法都是直接压缩生成本地文件, 但做 streaming 的话我们希望打包的模块有这样一个接口: 类似一个管道, 向一端逐步写入要压缩打包的内容, 从另一端逐步读取打包后的内容

综上, 第一种做法较简单, 一般来讲打包下载都采用的第一种做法。 通过抓取的 HTTP 响应头分析, Github 的打包下载采用了第一种做法, Dropbox 采用了第二种做法




2012/12/11 Chunlin Zhang <zhangc...@gmail.com>

依云

unread,
Dec 11, 2012, 4:28:50 AM12/11/12
to pyth...@googlegroups.com
这个我做过,很简单,tarfile.open 一个可读的对象到 HTTP 请求的写端(指定
fileobj=xxx),然后往里边加文件。

要压缩的话,就把 TarFile 开到一个 GzipFile 上,GzipFile 再连接到 HTTP 请
求上。

--
Best regards,
lilydjwg

Linux Vim Python 我的博客:
http://lilydjwg.is-programmer.com/
--
A: Because it obfuscates the reading.
Q: Why is top posting so bad?

Chunlin Zhang

unread,
Dec 11, 2012, 4:50:36 AM12/11/12
to python-cn`CPyUG`华蟒用户组



2012/12/11 依云 <lily...@gmail.com>

On Mon, Dec 10, 2012 at 07:37:37PM -0800, Chunlin Zhang wrote:
> windows下的hfs有个功能是页面右下角有个 http://host/~folder.tar?recursive
> 的链接,点击以后会把当前页面浏览的目录整个打包成.tar文件下载,即使文件很大也是点击以后马上可以下载的,所以我想它应该是没有实际生成这个folder.tar文件,而是边读边生成
>
> 我用uliweb开发web应用的时候想做个类似的功能,想对一个文件夹打包生成tar文件提供给http下载,如果文件夹内容很大的话,我也想像hfs这样不生成文件来做
>
> 但是看了python里的tarfile模块感觉没啥概念,可能要去研究一下tar文件的格式?
>
> 大家有啥想法给支支招,谢谢!

这个我做过,很简单,tarfile.open 一个可读的对象到 HTTP 请求的写端(指定
fileobj=xxx),然后往里边加文件。

要压缩的话,就把 TarFile 开到一个 GzipFile 上,GzipFile 再连接到 HTTP 请
求上。
之后再试试 

依云

unread,
Dec 11, 2012, 5:16:29 AM12/11/12
to pyth...@googlegroups.com
我曾经写的:

class BatchDownload(AuthMixin, tornado.web.RequestHandler):
@tornado.web.authenticated
@tornado.web.asynchronous
def get(self, paths):
paths = paths.split('//')
splitted_paths = []
for p in paths:
prefix, path = p.split('/', 1)
if not self.user_permission_for(prefix) & PERM_READ:
raise tornado.web.HTTPError(403)
splitted_paths.append((prefix, path))
pp = os.path.split(self.get_argument('pp'))[1]
if len(paths) == 1:
filename = os.path.splitext(os.path.split(paths[0])[1])[0]
else:
filename = os.path.split(pp)[1]
self.set_header('Content-Disposition', 'attachment; filename="%s.tar.gz"' % filename.replace('"', r'\"'))
self.set_header("Content-Type", "application/x-gzip")
self.tar = tarfile.open(mode='w|gz', fileobj=self)
args = []
for f in splitted_paths:
prefix, p = f
args.append((util.getfilepath('/'+p, CONF[prefix+'_dir']), p[len(pp)-2:]))
self.taradd(args)

def taradd(self, args):
if args:
self.tar.add(*args[0])
self.flush(callback=partial(self.taradd, args[1:]))
else:
self.tar.close()
self.finish()

Chunlin Zhang

unread,
Nov 7, 2015, 3:40:16 AM11/7/15
to python-cn`CPyUG`华蟒用户组
https://github.com/SpiderOak/ZipStream 可以做到哈 这个至少可以做到在不在硬盘或者内存中生成zip文件直接用流式生成
虽然还是没法像hfs那么强大做到可以支持断点续传,但至少能流式了


whycrying

unread,
Nov 7, 2015, 6:21:06 AM11/7/15
to pyth...@googlegroups.com
之前也参考过这个 https://github.com/SpiderOak/ZipStream 在 Tornado 里做类似的功能,是可以做到,
和 Gmail 的所有附件打包成 zip 文件并下载功能类似,
不过一个很严重的问题是文件名的编码( CP437 vs UTF-8 ),对于非 ASCII 的文件名在 zip 格式里面无解,最终放弃。
(它不像邮件附件标准 MIME 那样子可以把邮件附件的文件名使用某种编码方式将编码方式和编码过后的字节码放在一起)
( Gmail 的所有附件打包成 zip 文件并下载功能在下载链接处有个 zip 里文件名编码选择的下拉菜单,这是之前的设计,不知道后来改了没有)

Google: zip file encoding

比如:

Zip files and Encoding – I hate you.
https://marcosc.com/2008/12/zip-files-and-encoding-i-hate-you/

Non-UTF-8 encoding in ZIP file
https://blogs.oracle.com/xuemingshen/entry/non_utf_8_encoding_in

...




严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了Google网上论坛上的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com
要发帖到此群组,请发送电子邮件至pyth...@googlegroups.com
要查看更多选项,请访问https://groups.google.com/d/optout



--

Chunlin Zhang

unread,
Nov 7, 2015, 9:00:44 AM11/7/15
to python-cn`CPyUG`华蟒用户组
谢谢提醒
真奇怪,我在linux下测试怎么也有问题,照例说都应该是用utf8才对 但弄出来的仍然是乱码...
要不然还是tar文件比较靠谱?

您收到此邮件是因为您订阅了Google网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。
要退订此主题,请访问https://groups.google.com/d/topic/python-cn/q7rXVGVa0Bo/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+...@googlegroups.com

依云

unread,
Nov 7, 2015, 11:32:45 AM11/7/15
to pyth...@googlegroups.com
On Sat, Nov 07, 2015 at 10:00:32PM +0800, Chunlin Zhang wrote:
> 谢谢提醒
> 真奇怪,我在linux下测试怎么也有问题,照例说都应该是用utf8才对 但弄出来的仍然是乱码...
> 要不然还是tar文件比较靠谱?

不是。tar 和 Linux 文件系统一样,是 encoding-agnostic 的。也就是说,tar
会把文件名使用的那些字节原样存储,解包时原样拿出来。不过 Linux 世界现在
大都用 UTF-8 了,所以还好。不清楚在 Windows 上会发生什么。

7z 是知道文件名编码的。我没记错的话它使用的是 UTF-16。

Chunlin Zhang

unread,
Nov 8, 2015, 9:55:07 AM11/8/15
to python-cn`CPyUG`华蟒用户组
2015-11-08 0:31 GMT+08:00 依云 <lily...@gmail.com>:
On Sat, Nov 07, 2015 at 10:00:32PM +0800, Chunlin Zhang wrote:
> 谢谢提醒
> 真奇怪,我在linux下测试怎么也有问题,照例说都应该是用utf8才对 但弄出来的仍然是乱码...
> 要不然还是tar文件比较靠谱?

不是。tar 和 Linux 文件系统一样,是 encoding-agnostic 的。也就是说,tar
会把文件名使用的那些字节原样存储,解包时原样拿出来。不过 Linux 世界现在
大都用 UTF-8 了,所以还好。不清楚在 Windows 上会发生什么。

7z 是知道文件名编码的。我没记错的话它使用的是 UTF-16。
7z  格式好像更复杂和麻烦
要不然就是像上面说的下载前确认好编码,比如默认自动识别下如果浏览器表明了是 windows+zhCN就用gbk 之类的

--
Best regards,
lilydjwg

Linux Vim Python 我的博客:
http://lilydjwg.is-programmer.com/
--
A: Because it obfuscates the reading.
Q: Why is top posting so bad?

--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了 Google 网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。

要退订此主题,请访问https://groups.google.com/d/topic/python-cn/q7rXVGVa0Bo/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+...@googlegroups.com
要向此群组发帖,请发送电子邮件至 pyth...@googlegroups.com
要查看更多选项,请访问 https://groups.google.com/d/optout

Chunlin Zhang

unread,
Nov 8, 2015, 9:58:40 AM11/8/15
to python-cn`CPyUG`华蟒用户组
看 https://en.wikipedia.org/wiki/Comparison_of_archive_formats
这里说 unicode filenames, tar/zip/7z都是支持的吧...

R Shishioh

unread,
Nov 8, 2015, 10:16:00 AM11/8/15
to python-cn(华蟒用户组,CPyUG 邮件列表)
zip 也许并不支持,日本那边打包的带日文文件名的zip在windows上必定会乱码,别的系统不了解

在 2015年11月8日星期日 UTC+8下午10:58:40,Chunlin Zhang写道:

依云

unread,
Nov 8, 2015, 10:35:57 AM11/8/15
to pyth...@googlegroups.com
On Sun, Nov 08, 2015 at 10:58:28PM +0800, Chunlin Zhang wrote:
> 看 https://en.wikipedia.org/wiki/Comparison_of_archive_formats
> 这里说 unicode filenames, tar/zip/7z都是支持的吧...

tar,一个是说可以用 UTF-8 了,但是没有说一定是 UTF-8,或者哪里存了编码名。
另一个是扩展。

zip 后来是有编码信息的,但是具体用法我并不了解。反正乱码还是存在。

est

unread,
Nov 9, 2015, 10:04:52 PM11/9/15
to pyth...@googlegroups.com
这12年的老帖子怎么又被顶起来了。。。。。。。。。。。。

好吧,题外话,其实最好不用python做这个。用popen开个子进程流式处理这个最好。如果能把py主进程的http的fd直接共享给子进程,那就是高科技了!


顺便,最近才发现Ruby那边的zlib是支持绕开GVL利用多核的。




--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了 Google 网上论坛的“python-cn(华蟒用户组,CPyUG 邮件列表)”群组。
要退订此群组并停止接收此群组的电子邮件,请发送电子邮件到python-cn+...@googlegroups.com

Chunlin Zhang

unread,
Nov 10, 2015, 2:46:11 AM11/10/15
to python-cn`CPyUG`华蟒用户组
我看 https://en.wikipedia.org/wiki/Zip_(file_format) 这里有写:
  • 6.3.0: (2006)[14] Documented Unicode (UTF-8) filename storage. Expanded list of supported hash, compression (LZMAPPMd+), encryption algorithms.
是不是现在的压缩解压程序都还不支持这个版本的spec


--
邮件来自: `CPyUG`华蟒用户组(中文Python技术邮件列表)
规则: http://code.google.com/p/cpyug/wiki/PythonCn
详情: http://code.google.com/p/cpyug/wiki/CpyUg
严正: 理解列表! 智慧提问! http://wiki.woodpecker.org.cn/moin/AskForHelp
---
您收到此邮件是因为您订阅了Google网上论坛上“python-cn(华蟒用户组,CPyUG 邮件列表)”群组中的主题。

要退订此主题,请访问https://groups.google.com/d/topic/python-cn/q7rXVGVa0Bo/unsubscribe
要退订此群组及其所有主题,请发送电子邮件到python-cn+...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages