python - 在Python中为文件预分配磁盘空间而不改变其大小

标签 python disk diskspace fallocate

我正在编写一个程序,它可以同时从多个不同的服务器下载多个文件(当然,每个服务器一个下载线程!)。我担心磁盘上同时增长的多个文件会导致磁盘碎片,我想通过在磁盘上为完整文件的长度预分配空间来缓解这种情况(如 Content-Length header 所报告的)在开始下载之前,最好不要增加文件的表观长度(这样我只需以追加模式打开部分下载的文件即可恢复失败的下载)。

这可以以独立于平台的方式实现吗?

最佳答案

我做了一些谷歌搜索,发现 this lovely article一些 C 代码可以完全满足您在 Windows 上的要求。以下是转换为 ctypes 的 C 代码(为了便于阅读而编写):

    import ctypes
    import msvcrt
    # https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-setfileinformationbyhandle
    set_file_information = ctypes.windll.kernel32.SetFileInformationByHandle

    class AllocationInfo(ctypes.Structure):
        _fields_ = [('AllocationSize', ctypes.c_longlong)]
    
    def allocate(file, length):
        """Tell the filesystem to preallocate `length` bytes on disk for the specified `file` without increasing the
        file's length.
        In other words, advise the filesystem that you intend to write at least `length` bytes to the file.
        """
        allocation_info = AllocationInfo(length)
        retval = set_file_information(ctypes.c_long(msvcrt.get_osfhandle(file.fileno())),
                                      ctypes.c_long(5),  # constant for FileAllocationInfo in the FILE_INFO_BY_HANDLE_CLASS enum
                                      ctypes.pointer(allocation_info),
                                      ctypes.sizeof(allocation_info)
                                      )
        if retval != 1:
            raise OSError('SetFileInformationByHandle failed')

这会将文件在磁盘上的大小:如文件资源管理器中所示更改为您指定的长度(加上元数据的几千字节),但保持大小:不变。

然而,在我用谷歌搜索的半个小时里,我还没有找到在 POSIX 上做到这一点的方法。 Fallocate() 实际上与您所追求的完全相反:它将文件的表观长度设置为您给定的长度,但将其分配为磁盘上的稀疏范围,因此写入多个同时文件仍然会导致碎片。 Windows 具有 POSIX 所缺乏的文件管理功能,这不是很讽刺吗?

我最希望被证明是错误的,但我认为这是不可能的。

关于python - 在Python中为文件预分配磁盘空间而不改变其大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63275794/

相关文章:

python - 使用 Django channel 时如何使用 Channel 而不是 Group?

database - 需要操作系统 : getting base I/O unit size, “sync” 选项的磁盘驱动器管理数据,直接内存访问

linux - 主目录已满。如何增加它的大小?

R 如何在将 csv 文件写入磁盘之前估计其大小

python - Tensorflow Estimator : loss not decreasing when using tf. feature_column.embedding_column 用于分类变量列表

python - PsychoPy 中具有多种颜色的文本

Python - 对导入文件的更改不生效

objective-c - 如何在 cocoa 应用程序中获取 diskutil 信息输出

linux - 尝试从现有 for 循环中的文件读取

ios - 有没有办法确定应用程序在 iOS 中使用的磁盘空间量?