Python 实现字节数转文件大小
有时候我们需要将文件的字节数转换成文件大小的单位,如KB,MB,GB,TB。
字节和文件单位转换,一般通过1024换算一下就可以了。虽然这很简单,但其实,需要对字节数的范围进行判断,以便知道最后的结果是什么单位。所以这篇文章写了一个简单的换算工具,可以当成模块一样来使用,也可以直接复制函数到使用的地方,然后调用。
一、round()内置函数
# coding=utf-8
print(round(10, 2))
print(round(10/1, 2))
print(round(10/8, 3))
print(round(10/3, 3))
运行结果:
10
10.0
1.25
3.333
round()是Python的内置函数,第一个参数传入一个数字,第二个参数传入计算结果的小数精度。
返回值是一个数字,这个数字可以是整数或浮点数。
如果传入的数字是一个整数,则返回结果是一个整数。
如果传入的是一个浮点数,或者是一个计算公式。当计算结果的小数点后位数小于第二个参数时,则显示计算结果的精度。例如,10/8的结果是1.25,结果的小数点后是两位,即使指定的精度是3也只显示2位,后面不补0。
当计算结果的小数点后位数大于第二个参数时,计算结果的小数点后会四舍五入,小数点后的位数按第二个参数来保留。如10/3的结果是无限循环小数,指定精度是3则小数点后只保留3位。
在字节转文件大小单位时,一般都是保留两位小数,这里可以用round()函数来控制。
二、文件大小单位描述
在单位换算时,1KB是1024个字节。
比字节小的单位是比特(也叫位),一个字节等于8比特。
比字节大的是MB,1MB是1024KB。
1GB是1024MB,1TB是1024GB,...以此类推。
每两个相邻单位之间的差距都是1024倍。
三、实现字节转文件大小单位的模块
# coding=utf-8
import math
__all__ = ['pybyte']
def pybyte(size, dot=2):
size = float(size)
# 位 比特 bit
if 0 <= size < 1:
human_size = str(round(size / 0.125, dot)) + 'b'
# 字节 字节 Byte
elif 1 <= size < 1024:
human_size = str(round(size, dot)) + 'B'
# 千字节 千字节 Kilo Byte
elif math.pow(1024, 1) <= size < math.pow(1024, 2):
human_size = str(round(size / math.pow(1024, 1), dot)) + 'KB'
# 兆字节 兆 Mega Byte
elif math.pow(1024, 2) <= size < math.pow(1024, 3):
human_size = str(round(size / math.pow(1024, 2), dot)) + 'MB'
# 吉字节 吉 Giga Byte
elif math.pow(1024, 3) <= size < math.pow(1024, 4):
human_size = str(round(size / math.pow(1024, 3), dot)) + 'GB'
# 太字节 太 Tera Byte
elif math.pow(1024, 4) <= size < math.pow(1024, 5):
human_size = str(round(size / math.pow(1024, 4), dot)) + 'TB'
# 拍字节 拍 Peta Byte
elif math.pow(1024, 5) <= size < math.pow(1024, 6):
human_size = str(round(size / math.pow(1024, 5), dot)) + 'PB'
# 艾字节 艾 Exa Byte
elif math.pow(1024, 6) <= size < math.pow(1024, 7):
human_size = str(round(size / math.pow(1024, 6), dot)) + 'EB'
# 泽它字节 泽 Zetta Byte
elif math.pow(1024, 7) <= size < math.pow(1024, 8):
human_size = str(round(size / math.pow(1024, 7), dot)) + 'ZB'
# 尧它字节 尧 Yotta Byte
elif math.pow(1024, 8) <= size < math.pow(1024, 9):
human_size = str(round(size / math.pow(1024, 8), dot)) + 'YB'
# 千亿亿亿字节 Bront Byte
elif math.pow(1024, 9) <= size < math.pow(1024, 10):
human_size = str(round(size / math.pow(1024, 9), dot)) + 'BB'
# 百万亿亿亿字节 Dogga Byte
elif math.pow(1024, 10) <= size < math.pow(1024, 11):
human_size = str(round(size / math.pow(1024, 10), dot)) + 'NB'
# 十亿亿亿亿字节 Dogga Byte
elif math.pow(1024, 11) <= size < math.pow(1024, 12):
human_size = str(round(size / math.pow(1024, 11), dot)) + 'DB'
# 万亿亿亿亿字节 Corydon Byte
elif math.pow(1024, 12) <= size:
human_size = str(round(size / math.pow(1024, 12), dot)) + 'CB'
# 负数
else:
raise ValueError('{}() takes number than or equal to 0, but less than 0 given.'.format(pybyte.__name__))
return human_size
math.pow(x, y)返回的结果是x的y次方,单位之间是以倍数递增的,所以刚好适合。
上面的代码将转换的逻辑封装成一个函数,可以在任何需要换算的地方导入和调用,直接返回结果。
print(pybyte(0.5))
print(pybyte(724))
print(pybyte(1000 * 204, 3))
print(pybyte(1000 * 204))
print(pybyte(1000 * 1024 * 204, 3))
运行结果:
4.0b
724.0B
199.219KB
199.22KB
199.219MB
调用上面的函数,返回的结果与预期相同。
注意,根据保留的位数计算出最后的小数,如果最后一位是0,0不会显示,所以有时显示的长度会不一样。
不过,我们在看文件大小时,并不需要很高的精度,一般来说,大部分人对于MB的精度会关注,到KB就不会关注了。所以说,这个计算结果完全没有问题,可以在任何地方使用。