我正在尝试使用带有西里尔字符的文件名来读取图像文件。
ls /home/atin/test
ОД Д.bmp
现在我正在尝试阅读python 3中的'ОДД.bmp'
image_path='/home/atin/test/ОД Д.bmp'
import matplotlib.pyplot as plt
sample_image=plt.imread(image_path)
但是我收到了这个错误。
SystemError: <built-in function read_png> returned NULL without setting an error
但是os.listdir('/home/atin/test')
提供了以下输出
['\ udcd0 \ udc9e \ udcd0 \ udc94 \ udcd0 \ udc94.bmp']
如何将上述输出解码为原始文件名ОДД.bmp。 我在这里使用ubuntu中的python 3.6。
答案 0 :(得分:2)
您的系统配置了错误的区域设置。在Linux上,Python从语言环境中获取文件系统编解码器。来自sys.getfilesystemencoding()
documentation:
返回用于在Unicode文件名和字节文件名之间进行转换的编码名称。
[...]
- 在Unix上,编码是语言环境编码。
您有一个使用UTF-8的文件系统,但Python没有正确读取数据。
结果,UTF-8数据无法正确解码,出现解码错误,surrogateescape
error handler开始播放,并且已经保留了&#39;字节为low surrogate codepoints。
您可以通过使用相同的错误处理程序编码为UTF-8来解决此问题:
>>> '\udcd0\udc9e\udcd0\udc94 \udcd0\udc94.bmp'.encode('utf8', 'surrogateescape')
b'\xd0\x9e\xd0\x94 \xd0\x94.bmp'
结果恰好是您的文件名的正确UTF-8编码:
>>> '\udcd0\udc9e\udcd0\udc94 \udcd0\udc94.bmp'.encode('utf8', 'surrogateescape').decode('utf8')
'ОД Д.bmp'
您希望至少使用LC_CTYPE=en_US.UTF-8
,以避免此问题。在您的情况下,您似乎有LC_CTYPE=UTF-8
,这是无效的(您可以使用LC_CTYPE=en_SG.UTF-8
代替。)
另一种解决方法是使用 bytes 路径:
image_path = '/home/atin/test/ОД Д.bmp'.encode('utf8')