Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mac OS X中文件系统的Unicode编码在Python中不正确?_Python_Macos_Unicode_File Io_Filesystems - Fatal编程技术网

Mac OS X中文件系统的Unicode编码在Python中不正确?

Mac OS X中文件系统的Unicode编码在Python中不正确?,python,macos,unicode,file-io,filesystems,Python,Macos,Unicode,File Io,Filesystems,在OSX和Python中使用Unicode文件名有点困难。我试图在代码后面使用文件名作为正则表达式的输入,但文件名中使用的编码似乎与sys.getfilesystemencoding()告诉我的不同。以下面的代码为例: #!/usr/bin/env python # coding=utf-8 import sys,os print sys.getfilesystemencoding() p = u'/temp/s/' s = u'åäö' print 's', [ord(c) for c i

在OSX和Python中使用Unicode文件名有点困难。我试图在代码后面使用文件名作为正则表达式的输入,但文件名中使用的编码似乎与sys.getfilesystemencoding()告诉我的不同。以下面的代码为例:

#!/usr/bin/env python
# coding=utf-8

import sys,os
print sys.getfilesystemencoding()

p = u'/temp/s/'
s = u'åäö'
print 's', [ord(c) for c in s], s
s2 = s.encode(sys.getfilesystemencoding())
print 's2', [ord(c) for c in s2], s2
os.mkdir(p+s)
for d in os.listdir(p):
  print 'dir', [ord(c) for c in d], d
它的输出如下:

utf-8
s [229, 228, 246] åäö
s2 [195, 165, 195, 164, 195, 182] åäö
dir [97, 778, 97, 776, 111, 776] åäö
因此,文件系统编码是utf-8,但当我使用utf-8编码我的文件名时,它将与使用相同字符串创建目录名不同。我希望当我使用字符串åäö创建一个dir并读回它的名称时,它应该使用与我直接应用编码相同的代码

如果我们看一下代码点97778 97776111776,基本上是ASCII字符加上了变音符号,例如o+¨=ö,这使得它是两个字符,而不是一个。如何避免这种差异,Python中是否有一种编码方案与OS X的这种行为相匹配,为什么getfilesystemencoding()不能给出正确的结果


还是我搞砸了?

MacOS X使用一种特殊的分解UTF-8来存储文件名。例如,如果需要读入文件名并将其写入“普通”UTF-8文件,则必须对其进行规范化:

filename = unicodedata.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8')

从这里开始:

getfilesystemencoding()
将为您提供正确的响应(编码),但它不会告诉您正确的响应

特别是,HFS+文件系统使用UTF-8编码和接近“D”的规范化形式(这要求像
o
这样的组合字符分解为
)。HFS+还与Unicode版本3.2中的标准化形式相关联,如苹果的

Python的方法在表单之间进行转换,如果使用
ucd\u 3\u 2\u 0
对象作为调用的前缀,则可以将其约束到Unicode版本3.2:

filename = unicodedata.ucd_3_2_0.normalize('NFC', unicode(filename, 'utf-8')).encode('utf-8')

对于这些特定的字符,可以通过对文件名字符串执行以下regexp将其转换为无变音的unicode来解决问题:`m_aa=re.compile(ur“a\u0308”,re.I),m_ae=re.compile(ur“a\u030a”,re.I),m_oe=re.compile(ur“o\u0308”,re.I)谢谢,回答得很好,希望我能投票并接受这两个答案!实际上,它不是完全的NFD,但很接近。如果HFS+以分解的形式存储文件名,您是否会使用
normalise('NFD'…)
来匹配HFS+编码?node.js遇到了这个问题npm包
unorm
有一个非常好的接口。