Python 拷贝大文件分片大小问题

2019-06-01 14:37:47 +08:00
 wikinee

python 拷贝大文件一般套路是:

with open(src_file, "rb") as fr, open(dst_file, 'wb') as fw:  # fr 读文件
    while True:
        data = fr.read(4096)
        if not data:
            break
        fw.write(data)

后面跟一些异常处理,4096 这个是 4 KB,这个大小受什么因素影响?

写 1 * 1024 * 1024 行吗?我感觉性能完全够啊

2303 次点击
所在节点    Python
16 条回复
msg7086
2019-06-01 15:08:46 +08:00
1MB 当然可以。4KB 很可能就是随便写的一个数。

但是一般不会用 Python 去追求性能。高性能复制大文件还是直接走系统工具比较好吧。
swulling
2019-06-01 15:17:35 +08:00
为啥不用标准库 shutil,搞这种没人用的所谓套路
clino
2019-06-01 15:43:36 +08:00
自己对比测试一下不就知道了
wikinee
2019-06-01 16:01:11 +08:00
@msg7086 我再看看。
@swulling 即使是 shutil 也有缓存大小参数的,这不跟这问题一样吗
@clino 我自己测试打印时间倒是不难,但是害怕系统调度之类的其他因素会影响到结果
clino
2019-06-01 17:07:08 +08:00
怕受随机因素影响就多做几次嘛
zeddit
2019-06-01 17:13:35 +08:00
文件系统 block size 一般是 4k 吧
scriptB0y
2019-06-01 17:22:15 +08:00
@msg7086
@wikinee

4KB 不是随机的一个数,Block device 的读操作是按照 block size 来的,读操作按照 block size align 才会更快( size 是 block size 的倍数)。
scriptB0y
2019-06-01 17:23:49 +08:00
我写了一坨,但是后面的内容不知道为啥就是在 V2EX 发不出来,链接也发不出来...

我贴下 gist 链接转成的 base64 吧,查看方式:

echo aHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbGFpeGludGFvLzE0MTJmYTAwOTg5M2VkNDYwMGNmMTE0OGVkMDRhOWIxCg== | base64 -D

希望你能解答你的疑惑。
iwtbauh
2019-06-01 17:50:31 +08:00
和 block size 没有关系,你读的文件早就中间有文件系统层

应用程序 --- 文件系统层 --- 块设备层 --- scsi/nvme/mtd.... --- 硬件

如果你的程序是直接读写块设备而不是文件系统(常见的有镜像烧写软件),再考虑 block size 的问题。

直接读写文件时,文件系统会处理好这些低级细节并执行缓冲和缓存。

为什么这个值要大:

因为 IO 操作(不仅 IO 操作,是全部的系统调用)是很消耗 CPU 的(涉及特权级别切换等耗时操作,特别是 Intel 漏洞使这方面更加剧了)。对于一个文件而言,缓冲区越大意味着调用系统调用的次数越少。
msg7086
2019-06-02 02:48:06 +08:00
@scriptB0y 不过 block size 不一定是 4K 吧。
fuzhuo233
2019-06-02 08:07:59 +08:00
4k 是 Linux 的 page size 啊,这是文件缓存层层读文件的最小单位,即使应用层只读一个字节真实也会加载一个页缓存下来。少于一个 page 读多次会浪费 cpu 时间。详询 File Page Cache
scriptB0y
2019-06-02 10:08:11 +08:00
@msg7086 嗯,不一定。 不过一般是 4k,我那个链接后面有说可以用 stat 看 block size,只要是 block size 的倍数就可以
NoAnyLove
2019-06-02 11:33:42 +08:00
正确的拷贝大文件的正确套路是。。。。。有系统 API 就直接用系统 API,cpython/blob/master/Lib/shutil.py#L227
NoAnyLove
2019-06-02 11:34:24 +08:00
发个 github 链接需要验证手机号码?这是啥套路?
lowman
2019-06-03 11:13:21 +08:00
wikinee
2019-06-03 15:54:43 +08:00
@lowman 感谢回复。
如果不是需要知道每一行内容的话,rb 速率比 r 高,而且安全一些,
因为 r 遇到一些特殊字符还有可能提前退出。
另外这边讨论的是拷贝不是读取[捂脸]

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/569740

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX