如何在Python中确定utf-8编码字符串的字节长度?

27 投票
3 回答
36056 浏览
提问于 2025-04-16 21:39

我正在处理亚马逊S3的文件上传,但遇到了一个问题,就是文件名太长了。S3对文件名的长度有要求,它是按字节来限制的,而不是按字符。

根据文档的说明:

一个文件名是由一串Unicode字符组成,其UTF-8编码的长度最多为1024个字节。

我还想在文件名中加入一些元数据,所以我需要用Python来计算当前字符串的字节长度,以确保这些元数据不会让文件名变得太长(如果太长的话,我就得用一个单独的元数据文件了)。

我该如何确定UTF-8编码字符串的字节长度呢?我并不关心字符的数量,而是想知道实际存储这个字符串所用的字节数。

3 个回答

8

对字符串进行编码,然后用 len 来计算结果的长度,这个方法效果很好,其他答案也提到过。不过,这个过程需要创建一个临时的字符串副本,如果你处理的是非常大的字符串,这样做可能不是最优的选择(不过我觉得1024字节的字符串算不上“很大”)。UTF-8的结构让你可以很轻松地获取每个字符的长度,甚至不需要编码,尽管有时候编码一个字符可能更简单。我在这里展示了两种方法,它们应该会得到相同的结果。

def utf8_char_len_1(c):
    codepoint = ord(c)
    if codepoint <= 0x7f:
        return 1
    if codepoint <= 0x7ff:
        return 2
    if codepoint <= 0xffff:
        return 3
    if codepoint <= 0x10ffff:
        return 4
    raise ValueError('Invalid Unicode character: ' + hex(codepoint))

def utf8_char_len_2(c):
    return len(c.encode('utf-8'))

utf8_char_len = utf8_char_len_1

def utf8len(s):
    return sum(utf8_char_len(c) for c in s)
12

使用字符串的'encode'方法可以把字符字符串转换成字节字符串,然后像平常一样使用len()来计算长度:

>>> s = u"¡Hola, mundo!"                                                      
>>> len(s)                                                                    
13 # characters                                                                             
>>> len(s.encode('utf-8'))   
14 # bytes
41
def utf8len(s):
    return len(s.encode('utf-8'))

在Python 2和3中都能正常工作。

撰写回答