QFile无法打开包含Unicode字符的文件名

3
我遇到了一个PySide的问题。我正在处理一些图像,使用QtCore.QImage,并注意到路径名中包含Unicode字符的图像文件无法打开。
所以我开始调查,并发现QFile也存在同样的问题。
我尝试使用'utf8'编码的字节串和解码后的Unicode字符串,但结果相同。
我还尝试使用那些QFile.encodeName和QFile.decodeName函数,但这只是从文件名中剥离了非ASCII字符。
我制作了这个脚本来演示:
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

from PySide.QtCore import QFile, QIODevice

try:
    os.makedirs(u'/tmp/qttest')
except:
    pass #probably dir just exists
os.chdir(u'/tmp/qttest')

def make_file(fn):
    f = open(fn, 'w')
    f.close()

def check_file(fn):
    f = QFile(fn)
    f.open(QIODevice.ReadOnly)
    return f.isReadable()    

fna = u'somefile.txt'
fnu = u'einhverskrá.txt'

make_file(fna)
make_file(fnu)

print fna+u' was opened successfully: ', check_file(fna)
print fnu+u' was opened successfully: ', check_file(fnu)

print fna+u' exists: ', os.path.exists(fna)
print fnu+u' exists: ', os.path.exists(fnu)

输出

somefile.txt was opened successfully:  True
einhverskrá.txt was opened successfully:  False
somefile.txt exists:  True
einhverskrá.txt exists:  True

有人能解释一下这个吗?

更新 在查看源代码后,我发现QFile.open()在Unix系统上总是通过此函数传递文件名:

static QString locale_decode(const QByteArray &f)
{
#if defined(Q_OS_DARWIN)
    // Mac always gives us UTF-8 and decomposed, we want that composed...
    return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
#elif defined(Q_OS_SYMBIAN)
    return QString::fromUtf8(f);
#else
    return QString::fromLocal8Bit(f);
#endif
}

这将导致字符串中的Unicode字符被剥离。


你能用 open() 正常打开它们吗? - Alex L
没错,open() 函数运行正常。 - Steinthor.palsson
这个能用吗?QFile(fn.encode(sys.getfilesystemencoding())) - Avaris
strace -o traced.txt -v -e trace=open python script.py,并查看它是否尝试打开一些奇怪的东西。 - sherpya
@sherpya:是的。我在结尾得到了这一行 open("einhverskr.txt", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) ... 看起来像是qt刚好去掉了Unicode字符。 - Steinthor.palsson
@Avaris:不,文件系统编码是utf8。 - Steinthor.palsson
1个回答

2
是的,我相信我已经找到了解决我的问题的方法。
from PySide.QtCore import QTextCodec
QTextCodec.setCodecForLocale(QTextCodec.codecForName('UTF-8'))

经过这样的处理,Unicode文件名似乎得到了正确解析。

不过我需要确认这个修复是否会对其他平台产生负面影响。


哇!在C++中也是这样的!QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); 当然还需要一个 #include <QTextCodec> - Alexis Wilke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接