2011-03-04 59 views
34

我正在使用一個讀取文件並以字節爲單位返回其大小的庫。在Python中轉換文件大小的更好方法

該文件大小然後顯示給最終用戶;爲了讓他們更容易理解它,我明確地將文件大小除以1024.0 * 1024.0來將文件大小轉換爲MB。當然,這是有效的,但我想知道是否有更好的方法來在Python中做到這一點?

更好的是,我的意思是可能是一個stdlib函數,可以根據我想要的類型操縱大小。就像我指定MB一樣,它會自動將它除以1024.0 * 1024.0。在這些線上進行一些處理。

+4

所以寫一個。另外請注意,許多系統現在使用MB來表示10^6而不是2^20。 – 2011-03-04 13:08:16

+1

@A A,@tc:請記住,在SI和IEC標準是'KB(千)爲1.000 Byte'和'昆明植物研究所(吉備)爲1.024 Byte'。見http://en.wikipedia.org/wiki/Kibibyte。 – Bobby 2011-03-04 13:12:55

+1

@Bobby:kB其實意味着「千貝」,等於10000分貝。 SI沒有字節的單位。 IIRC,IEC建議KiB但不定義kB或KB。 – 2011-03-12 04:41:00

回答

53

hurry.filesize,將以字節爲單位的大小,如果它出一個漂亮的字符串。

>>> from hurry.filesize import size 
>>> size(11000) 
'10K' 
>>> size(198283722) 
'189M' 

或者,如果你想1K = = 1000(這是大多數用戶承擔):

>>> from hurry.filesize import size, si 
>>> size(11000, system=si) 
'11K' 
>>> size(198283722, system=si) 
'198M' 

它具有IEC的支持,以及(但沒有記錄):

>>> from hurry.filesize import size, iec 
>>> size(11000, system=iec) 
'10Ki' 
>>> size(198283722, system=iec) 
'189Mi' 

因爲它是由Awesome Martijn Faassen編寫的,所以代碼很小,清晰且可擴展。編寫自己的系統非常簡單。

這裏是一個:

mysystem = [ 
    (1024 ** 5, ' Megamanys'), 
    (1024 ** 4, ' Lotses'), 
    (1024 ** 3, ' Tons'), 
    (1024 ** 2, ' Heaps'), 
    (1024 ** 1, ' Bunches'), 
    (1024 ** 0, ' Thingies'), 
    ] 

使用像這樣:

>>> from hurry.filesize import size 
>>> size(11000, system=mysystem) 
'10 Bunches' 
>>> size(198283722, system=mysystem) 
'189 Heaps' 
+0

完美!除了想讓它適用於我的案例,我想知道它是這樣的。 – user225312 2011-03-04 13:45:48

9

相反的1024.0 * 1024.0大小除數可以使用1<<20拿到兆,1<<30得到千兆字節等

我定義了一個常數MBFACTOR = float(1<<20)然後可以使用字節,即:megas = size_in_bytes/MBFACTOR

+5

它不是'>>'? – Tjorriemorrie 2014-08-08 12:54:16

64

下面是我用:

import math 

def convert_size(size_bytes): 
    if size_bytes == 0: 
     return "0B" 
    size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") 
    i = int(math.floor(math.log(size_bytes, 1024))) 
    p = math.pow(1024, i) 
    s = round(size_bytes/p, 2) 
    return "%s %s" % (s, size_name[i]) 

注:大小應以字節爲單位進行發送。

+10

如果您以字節爲單位發送大小,則只需添加「B」作爲size_name的第一個元素即可。 – tuxGurl 2013-03-25 17:13:43

+0

真棒歡呼! – matcheek 2013-05-06 14:01:55

+0

當文件大小爲0時,它將失敗。日誌(0,1024)未定義!你應該在這個語句之前檢查0字節大小寫i = int(math.floor(math.log(size,1024))))。 – genclik27 2014-05-07 13:57:43

12

下面是緊湊的函數來計算大小

def GetHumanReadable(size,precision=2): 
    suffixes=['B','KB','MB','GB','TB'] 
    suffixIndex = 0 
    while size > 1024 and suffixIndex < 4: 
     suffixIndex += 1 #increment the index of the suffix 
     size = size/1024.0 #apply the division 
    return "%.*f%s"%(precision,size,suffixes[suffixIndex]) 

對於更詳細的輸出,反之亦然操作請參見:http://code.activestate.com/recipes/578019-bytes-to-human-human-to-bytes-converter/

-2

正確地對所有文件大小這項工作:

import math 
from os.path import getsize 

def convert_size(size): 
    if (size == 0): 
     return '0B' 
    size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") 
    i = int(math.floor(math.log(size,1024))) 
    p = math.pow(1024,i) 
    s = round(size/p,2) 
    return '%s %s' % (s,size_name[i]) 

print(convert_size(getsize('file_name.zip'))) 
+3

是否真的值得複製「sapam」的答案....不......下一次只是評論。 – Mayhem 2016-10-20 03:18:40

+0

另一個答案必須複製到其他地方,然後再複製到這裏......實際上,我們鼓勵原創的答案。 – FaithReaper 2017-11-06 15:57:19

3

只是爲了防止任何人尋找這個問題的背面(正如我確實那樣),這裏是什麼對我來說KS:

def get_bytes(size, suffix): 
    size = int(float(size)) 
    suffix = suffix.lower() 

    if suffix == 'kb' or suffix == 'kib': 
     return size << 10 
    elif suffix == 'mb' or suffix == 'mib': 
     return size << 20 
    elif suffix == 'gb' or suffix == 'gib': 
     return size << 30 

    return False 
-1

這裏的@羅密歐的反向實施的另一個版本,可處理一個輸入字符串。

import re 

def get_bytes(size_string): 
    try: 
     size_string = size_string.lower().replace(',', '') 
     size = re.search('^(\d+)[a-z]i?b$', size_string).groups()[0] 
     suffix = re.search('^\d+([kmgtp])i?b$', size_string).groups()[0] 
    except AttributeError: 
     raise ValueError("Invalid Input") 
    shft = suffix.translate(str.maketrans('kmgtp', '12345')) + '0' 
    return int(size) << int(shft) 
-1

類似亞倫杜克大學的答覆,但更多的 「Python的」;)

import re 


RE_SIZE = re.compile(r'^(\d+)([a-z])i?b?$') 

def to_bytes(s): 
    parts = RE_SIZE.search(s.lower().replace(',', '')) 
    if not parts: 
     raise ValueError("Invalid Input") 
    size = parts.group(1) 
    suffix = parts.group(2) 
    shift = suffix.translate(str.maketrans('kmgtp', '12345')) + '0' 
    return int(size) << int(shift) 
-1

我是新來編程。我想出了下面這個函數,它將給定的文件大小轉換爲可讀格式。

def file_size_converter(size): 
    magic = lambda x: str(round(size/round(x/1024), 2)) 
    size_in_int = [int(1 << 10), int(1 << 20), int(1 << 30), int(1 << 40), int(1 << 50)] 
    size_in_text = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] 
    for i in size_in_int: 
     if size < i: 
      g = size_in_int.index(i) 
      position = int((1024 % i)/1024 * g) 
      ss = magic(i) 
      return ss + ' ' + size_in_text[position] 
1

這裏我的兩分錢,這允許鑄造上下,並增加了可定製精度:

def convertFloatToDecimal(f=0.0, precision=2): 
    ''' 
    Convert a float to string of decimal. 
    precision: by default 2. 
    If no arg provided, return "0.00". 
    ''' 
    return ("%." + str(precision) + "f") % f 

def formatFileSize(size, sizeIn, sizeOut, precision=0): 
    ''' 
    Convert file size to a string representing its value in B, KB, MB and GB. 
    The convention is based on sizeIn as original unit and sizeOut 
    as final unit. 
    ''' 
    assert sizeIn.upper() in {"B", "KB", "MB", "GB"}, "sizeIn type error" 
    assert sizeOut.upper() in {"B", "KB", "MB", "GB"}, "sizeOut type error" 
    if sizeIn == "B": 
     if sizeOut == "KB": 
      return convertFloatToDecimal((size/1024.0), precision) 
     elif sizeOut == "MB": 
      return convertFloatToDecimal((size/1024.0**2), precision) 
     elif sizeOut == "GB": 
      return convertFloatToDecimal((size/1024.0**3), precision) 
    elif sizeIn == "KB": 
     if sizeOut == "B": 
      return convertFloatToDecimal((size*1024.0), precision) 
     elif sizeOut == "MB": 
      return convertFloatToDecimal((size/1024.0), precision) 
     elif sizeOut == "GB": 
      return convertFloatToDecimal((size/1024.0**2), precision) 
    elif sizeIn == "MB": 
     if sizeOut == "B": 
      return convertFloatToDecimal((size*1024.0**2), precision) 
     elif sizeOut == "KB": 
      return convertFloatToDecimal((size*1024.0), precision) 
     elif sizeOut == "GB": 
      return convertFloatToDecimal((size/1024.0), precision) 
    elif sizeIn == "GB": 
     if sizeOut == "B": 
      return convertFloatToDecimal((size*1024.0**3), precision) 
     elif sizeOut == "KB": 
      return convertFloatToDecimal((size*1024.0**2), precision) 
     elif sizeOut == "MB": 
      return convertFloatToDecimal((size*1024.0), precision) 

添加TB等,如你所願。

相關問題