在Linux系统上,文件系统存储字节,只存储字节。
所以,如果一个程序认为应该发送文件名,比方说,
UTF-16
或ISO-8859-7
编码,它将采用“Νικόλαος”之类的字符串
并且文件系统将看到如下字节:
py> s = 'Νικόλαος'
py> s.encode('UTF-16be')
b'\x03\x9d\x03\xb9\x03\xba\x03\xcc\x03\xbb\x03\xb1\x03\xbf\x03\xc2'
py> s.encode('iso-8859-7')
b'\xcd\xe9\xea\xfc\xeb\xe1\xef\xf2'
请注意,相同的字符串会为您提供完全不同的字节。和 同样,相同的字节会给你不同的字符串,具体取决于 你使用的编码。
现在,如果您尝试使用期望UTF-8的程序读取文件名, 它会看到某种mojibake垃圾字符,或者得到一些 有点错误:
py> s.encode('UTF-16be').decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x9d in position 1:
invalid start byte
py> s.encode('iso-8859-7').decode('utf-8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcd in position 0:
invalid continuation byte
我在该目录中有一些文件,其中文件名作为字节无效 由python3解码为UTF-8,但我的系统设置为使用UTF-8。所以要解决这个问题 需要使用一些不太关心的工具来重命名文件 关于编码。
所以我试过了:
mv'Euxi touIhsou.mp3''ΕυχήτουΙησού.mp3'
string = 'Ευχή του Ιησού.mp3'
above string in unknown charset bytes = '\305\365\367\336\364\357\365\ \311\347\363\357\375.mp3'
那么如何编写以下代码以便正确地将files.py读成希腊文件名呢?
# Compute a set of current fullpaths
fullpaths = set()
path = "/home/nikos/public_html/data/apps/"
for root, dirs, files in os.walk(path):
for fullpath in files:
fullpaths.add( os.path.join(root, fullpath) )
# Load'em
for fullpath in fullpaths:
try:
# Check the presence of a file against the database and insert if it doesn't exist
cur.execute('''SELECT url FROM files WHERE url = %s''', (fullpath,) )
data = cur.fetchone()
Encoding = string - &gt; (使用了一些字符集) - &gt; charset字节 解码=字节 - &gt; (必须知道使用了什么字符集) - &gt;原始字符串
我是否正确地指出,整个编码/解码过程的键是使用/必须使用的字符集?
我们不知道他们使用了密钥(charset),但是我们知道字符串的原始形式,所以如果我们编写一个python脚本来解码mojabike字节流到所有可用的字符集,那么就会发生这种情况。原始字符串将显示回来。