【问题标题】:Get percentage from byte to gb python获取从字节到gb python的百分比
【发布时间】:2019-07-08 01:07:30
【问题描述】:

我正在开发一个程序来检查文件夹大小,然后打印出最大使用量的百分比,即 50GB。我遇到的问题是,如果数据只有 1mb 或不是 gb 的小数字,我没有得到准确的百分比。如何改进我的代码来解决这个问题。

import math, os

def get(fold):
        total_size = 0

        for dirpath, dirnames, filenames in os.walk(fold):
            for f in filenames:
                fp = os.path.join(dirpath, f)
                size = os.path.getsize(fp)
                total_size += size

        size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
        i = int(math.floor(math.log(total_size, 1024)))
        p = math.pow(1024, i)
        s = round(total_size / p, 2)

        return "%s %s" % (s, size_name[i])

per = 100*float(get(fold))/float(5e+10)
print(per)

【问题讨论】:

  • 您的预期结果是什么?没有比0.00% 更好的东西了,只有小数点后两位。您可以考虑增加round 呼叫中的小数位数。
  • @Selcuk 在我转换它之后。然后去计算我的文件是 500mb 的百分比,它返回​​ 9%。什么时候应该返回 0.5。
  • 为什么它会返回 0.5 而不是 1%?在任何情况下,您都应该添加一个无法按预期工作的示例案例。它对我来说很好。
  • @Selcuk 嗯,500MB 是 50GB 的 0.5%,不是吗?
  • 不,不是……

标签: python math percentage filesize calculation


【解决方案1】:

您可能低估的一个地方是您在不考虑块大小的情况下将文件大小相加。例如,在我的系统上,分配块大小为 4096 字节。所以如果我'echo 1 > test.txt',这个 1 字节的文件会占用 4096 字节。我们可以重新编写代码来尝试解释块:

import math
import os

SIZE_NAMES = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")

def get(fold):
    total_size = 0

    for dirpath, _, filenames in os.walk(fold):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            stat = os.stat(fp)
            size = stat.st_blksize * math.ceil(stat.st_size / float(stat.st_blksize))
            total_size += size

    i = int(math.floor(math.log(total_size, 1024)))
    p = math.pow(1024, i)
    s = round(total_size / p, 2)

    return "%s %s" % (s, SIZE_NAMES[i])

虽然getsize() 计数不足会影响所有文件,但按百分比计算,它对较小文件的影响更大。当然,目录节点也占用空间。另外,这个计算有几个问题:

per = 100*float(get(fold))/float(5e+10)

首先,它失败了,因为fold() 返回了一个类似'122.23 MB' 的字符串,而float() 不喜欢它。其次,它没有考虑到float()代码中已调整但此处未调整的数字的单位。最后,它没有解决千兆字节与千兆字节的问题(如果没有别的,请在评论中。)即该空间在fold() 代码中按 1024 次方减少,但在此处除以 1000 次方。我的返工:

number, unit = get(fold).split()  # "2.34 MB" -> ["2.34", "MB"]
number = float(number) * 1024 ** SIZE_NAMES.index(unit)  # 2.34 * 1024 ** 2
print("{0:%}".format(number / 500e9))  # percentage of 500GB

【讨论】:

  • 我在使用您的代码时收到此错误? AttributeError: 'nt.stat_result' object has no attribute 'st_blksize'
  • @cdw100100,它适用于我系统上的 Python 2 和 3,所以我猜这是一个特定于操作系统的东西,因为这是一个特定于操作系统的接口。 IE。我猜你是在 Windows 上?
  • @cdw100100,如果您找不到特定于 Windows 的方法来通过 Python 获取块大小,则可以替换为常量,因为块大小不应在目录中的文件之间更改.如果您在 Windows 10 上找不到这个值,您可以使用常数 4096 并向上或向下调整 2 的幂,直到已知文件夹对您的代码和操作系统自己的实用程序进行测量。
  • 我只是想确保我计算百分比的方式是正确的?
  • @cdw100100,我相信你计算百分比的方式有几个错误。我已经用关于这个的解释和代码更新了我的答案。
【解决方案2】:

您在代码中混杂了一些东西;例如,您的函数 get() 返回一个字符串,但您稍后尝试将其转换为 float

我建议将其分开一点。首先是一个格式化大小的函数(我从其他stackoverflow问题中得到了一些想法):

SIZE_UNITS = ['', 'K', 'M', 'G', 'T']

def format_size(size_in_bytes):
    if size_in_bytes == 0:
        return '0.0 B'

    exp = math.floor(math.log(size_in_bytes, 1024))
    size = size_in_bytes / math.pow(1024, exp)
    return '{:.1f} {}B'.format(
        size,
        SIZE_UNITS[exp])

你有一个计算目录大小的函数和一个很好地打印信息的函数:

def get_size_of_dir(dir_path):
    total_size = 0

    for dir_path, dir_list, file_list in os.walk(dir_path):
        for filename in file_list:
            f = os.path.join(dir_path, filename)
            size = os.path.getsize(f)
            total_size += size

    return total_size

def print_info(dir_path, capacity):
    total_size = get_size_of_dir(dir_path)
    percent = total_size * 100.0 / capacity

    print()
    print('Directory:     "{}"'.format(dir_path))
    print('capacity       {:>10s}'.format(format_size(capacity)))
    print('total_size     {:>10s}'.format(format_size(total_size)))
    print('percent used   {:8.1f} %'.format(percent))

在我的机器上看起来像这样:

# 1024**1 == > 1 KB
# 1024**2 == > 1 MB
# 1024**3 == > 1 GB
>>> capacity = 5 * 1024**3

>>> for folder in ('/home/ralf/Documents/', '/home/ralf/Downloads/'):
...     print_info(folder, capacity)

Directory:     "/home/ralf/Documents/"
capacity           5.0 GB
total_size       721.7 MB
percent used       14.1 %

Directory:     "/home/ralf/Downloads/"
capacity           5.0 GB
total_size         1.3 GB
percent used       25.7 %

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-29
    • 2018-10-14
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多