python - readinto() 替换?

标签 python arrays fromfile

在 Python 中使用直接的方法复制文件通常是这样的:

def copyfileobj(fsrc, fdst, length=16*1024):
    """copy data from file-like object fsrc to file-like object fdst"""
    while 1:
        buf = fsrc.read(length)
        if not buf:
            break
        fdst.write(buf)

(顺便说一句,此代码片段来自 shutil.py)。

不幸的是,这在我的特殊用例(涉及线程和非常大的缓冲区)中有缺点[稍后添加斜体部分]。首先,这意味着每次调用 read() 都会分配一个新的内存块,当 buf 在下一次迭代中被覆盖时,该内存将被释放,只是为了相同的目的再次分配新的内存。这会减慢整个过程并给主机带来不必要的负载。

为了避免这种情况,我使用了 file.readinto() 方法,不幸的是,该方法被记录为已弃用且“不要使用”:

def copyfileobj(fsrc, fdst, length=16*1024):
    """copy data from file-like object fsrc to file-like object fdst"""
    buffer = array.array('c')
    buffer.fromstring('-' * length)
    while True:
        count = fsrc.readinto(buffer)
        if count == 0:
            break
        if count != len(buffer):
            fdst.write(buffer.toString()[:count])
        else:
            buf.tofile(fdst)

我的解决方案有效,但也有两个缺点:首先,不使用 readinto()。它可能会消失(文档说)。其次,使用 readinto() 我无法决定要读入缓冲区的字节数,而使用 buffer.tofile() 我无法决定要写入多少字节,因此最后一个 block 的特殊情况很麻烦(这也是不必要的贵)。

我查看了 array.array.fromfile(),但它不能用于读取“全部”(读取,然后抛出 EOFError 并且不分发已处理的项目数)。它也不是结束特例问题的解决方案。

是否有合适的方法来做我想做的事?也许我只是忽略了一个简单的缓冲区类或类似的东西,它可以满足我的需求。

最佳答案

This code snippet is from shutil.py

这是一个标准库模块。为什么不直接使用它呢?

First, it means that with each call of read() a new memory chunk is allocated and when buf is overwritten in the next iteration this memory is freed, only to allocate new memory again for the same purpose. This can slow down the whole process and put unnecessary load on the host.

与实际从磁盘中获取一页数据所需的工作量相比,这是微不足道的。

关于python - readinto() 替换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9791780/

相关文章:

python - 可用内存和总内存始终相同

python - 了解 Docker/Docker-Compose 上的 Gunicorn 和 Flask

arrays - 创建自定义类的数组并初始化它问题

arrays - 时间 O(n) 中数组内元素的频率算法

javascript - 将 HTML 表格转换为数组 (JavaScript)

python - 从 Python 中的二进制文件中提取特定字节

python - 使用 python 绘制数千个文件

python - http响应与站点和代码输出不同的原因是什么?

python - 压缩文件上的高效 numpy.fromfile?

python - functools.wraps 和 update_wrapper 有什么区别