【问题标题】:How to get raw disk or block device size in Windows with Python如何使用 Python 在 Windows 中获取原始磁盘或块设备大小
【发布时间】:2013-06-26 19:23:38
【问题描述】:

如果我只知道设备名称是“\.\PhysicalDrive0”而没有文件系统或卷标,如何从 Windows 中的块设备或原始磁盘获取大小?

我尝试了以下方法:

fd = os.open(r"\.\PhysicalDrive0", os.O_RDONLY)

os.lseek(fd, 0, os.SEEK_END)

它在 Linux 上运行良好,但在 Windows 上总是返回“OSError: [Errno 22] Invalid argument”。

我也尝试了 ctypes.windll.kernel32.GetDiskFreeSpaceExW(),但它似乎只适用于具有文件系统和分配卷标的磁盘。

对原始磁盘或块设备执行此操作的正确方法是什么?

提前致谢。

【问题讨论】:

  • stackoverflow.com/questions/7135398/… 可能会回答您的问题。
  • 谢谢,这是很棒的信息。现在我可以写信了,但是当我使用 .seek(0,2) 或 .seek(0,os.SEEK_END) 来获取大小时,它什么也不返回,似乎不知道结尾在哪里设备。
  • 现在您似乎正在使用与文件对象关联的 seek 方法(seek,而不是 lseek),您是否将 os.open 返回的文件描述符更改为文件对象?你可以通过使用 os.fdopen 来做到这一点。
  • 是的,像 fo=os.fdopen(os.open("\\\\.\\PhysicalDrive3", os.O_RDONLY|os.O_BINARY), "rb+") 和 fo.seek (0,2) 不起作用

标签: python windows filesize diskspace block-device


【解决方案1】:

我有一个解决方案.. 但它并不漂亮。使用磁盘部分。不幸的是,如果需要,它不会为您提供确切的字节大小,但它会为您提供人类可读的字符串。

import tempfile
import subprocess
import re
import os

def query_diskpart(command):
    """Run command script for diskpart.

    Args:
        command(str): String of all commands to run against diskpart
    Returns:
        String of all diskpart standard output
    Size Effects:
        Creates a temporary file(and then deletes it)
        Creates a subprocess to run diskpart
    """
    with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_handle:
        temp_handle.write(command)
    # The temporary file needs to be closed before opening with diskpart
    diskpart_handle = subprocess.Popen(["diskpart", '/s', temp_handle.name], stdout=subprocess.PIPE)
    output, _ = diskpart_handle.communicate()

    os.remove(temp_handle.name)
    return output

def match_drive_size(diskpart_output, disk_num):
    """Get drive size from diskpart output.

    Args:
        diskpart_output(str): String of diskpart standard output
        disk_num(int): Number of PhysicalDrive to match against
    Returns:
        Human readable size of drive.
    Raises:
        ValueError if drive doesn't exist.
        """

    # Break up gigantic output string
    output_lines = diskpart_output.decode().split(os.linesep)
    # Apply regular expression to every line, but it should only match one
    matches = [re.match(".*Disk %s\s*(.*)" % disk_num, line) for line in output_lines]
    size = None
    for match in matches:
        if match:
            # Get first subgroup (parens above)
            size_line = match.group(1)
            # Split by whitespace
            size_list = re.split("\s*", size_line)
            # Merge numerical value + units
            # ['256', 'GB'] becomes 256GB
            size = ''.join(size_list[1:3])
            break
    else:
        raise ValueError("PHYSICALDRIVE%s does not exist", disk_num)
    return size

def get_drive_size(disk_num):
    """Get Windows Drive size.

    Args:
        disk_num(int): The Physical Drive Number
            e.g. for PHYSICALDRIVE0 put 0
    Returns:
        Human readable string of the drive size
    """
    output = query_diskpart("list disk\n")
    drive_size = match_drive_size(output, disk_num)
    return drive_size

if __name__ == "__main__":
    print(get_drive_size(0))

【讨论】:

    【解决方案2】:

    使用wmi 模块

    import wmi
    c = wmi.WMI()
    [drive] = c.Win32_DiskDrive(Index=0)
    print("The disk has %s bytes" % drive.size)
    print("Or %s GB" % int(int(drive.size) / 1024**3))
    

    The disk has 320070320640 bytes
    Or 298 GB

    此代码在 WMI 接口中查询索引等于 0Win32_DiskDrive 对象(因此只有一个结果,结果是 PHYSICALDRIVE0)。 drive 对象有一个名为 size 的属性,它是一个包含驱动器大小(以字节为单位)的字符串。

    【讨论】:

      猜你喜欢
      • 2017-12-06
      • 2012-02-22
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多