Python QFileInfo vs QFile测试文件是否可写

Python QFileInfo vs QFile测试文件是否可写,python,qt,pyqt,file-permissions,Python,Qt,Pyqt,File Permissions,我正在使用PyQt,在用Windows测试我的应用程序时,我注意到了奇怪的行为(在Linux上一切正常) 我有一个可以读写的文件,我想从应用程序中测试它: >>> from PyQt4.QtCore import QFile, QFileInfo >>> f1 = QFileInfo("C:\Users\Maxime\Desktop\script.py") >>> f2 = QFile("C:\Users\Maxime\Desktop\sc

我正在使用PyQt,在用Windows测试我的应用程序时,我注意到了奇怪的行为(在Linux上一切正常)

我有一个可以读写的文件,我想从应用程序中测试它:

>>> from PyQt4.QtCore import QFile, QFileInfo

>>> f1 = QFileInfo("C:\Users\Maxime\Desktop\script.py")
>>> f2 = QFile("C:\Users\Maxime\Desktop\script.py")

>>> f1.isWritable()
True
>>> f2.isWritable()
False
因此,在该测试用例中,
QFile
似乎是错误的。但是,在另一个只读文件上:

>>> f1 = QFileInfo("C:\Program Files (x86)\MySoftware\stuff\script.py")
>>> f2 = QFile("C:\Program Files (x86)\MySoftware\stuff\script.py")

>>> f1.isWritable()
True
>>> f2.isWritable()
False
现在,这是
QFileInfo
,这是错误的

所以我决定也许我应该使用
os.access

>>> import os

>>> os.access("C:\Users\Maxime\Desktop\script.py")
True
>>> os.access("C:\Program Files (x86)\MySoftware\stuff\script.py")
True
因此,
os.access
在一种情况下也是错误的,返回的结果与
QFileInfo
相同

我有很多问题:

  • 我不熟悉Windows,有什么我遗漏的吗
  • 使用Qt,我可以使用
    QFileInfo
    QFile
    来测试文件是否可以写入。我应该用一个而不是另一个吗
  • 如果这只是Qt(和Python???)中的一个bug,我希望有一个可以在Linux和Mac操作系统上工作的解决方案
编辑:

Frank的一条非常有趣的评论解释说,QFile::isWritable()将始终返回False,因为我还没有打开该文件

>>> f = QFile("C:\Users\Maxime\Desktop\script.py")
>>> f.open(QFile.WriteOnly)
True
>>> f.isWritable()
True

>>> f = QFile("C:\Program Files (x86)\MySoftware\stuff\script.py")
>>> f.open(QFile.WriteOnly)
False
>>> f.isWritable()
False

要检查可写性,使用哪一个并不重要

QFileInfo的主要区别在于,出于性能原因,它缓存了一些有关目标文件的信息。但是,您可以使用该方法重新读取信息,也可以使用完全关闭缓存

此外,如问题注释中所述,如果文件尚未打开,QFile.iswriteable将返回False。这不是一个bug。文档清楚地表明检查文件的格式。在打开文件之前,该值将为零(QIODevice.NotOpen),如果未指定,则默认为QIODevice.ReadWrite

唯一需要注意的另一个问题是,QFileInfo.isWritable等方法是特定于当前用户的。用于其他用户类别的所有权信息(但请注意)。这类似于使用
os.access
os.stat
之间的区别

最后,这里有一个测试可写性的简单脚本:

import os, stat, sip

sip.setapi('QString', 2)
from PyQt4.QtCore import QTemporaryFile, QFile, QFileInfo

tmp = QTemporaryFile()
tmp.setAutoRemove(False)
tmp.open()
tmp.close()

path = tmp.fileName()

info = QFileInfo(path)
print('File: %s' % info.filePath())
print('')
print('Qt Writable: %s' % info.isWritable())
print('Qt Permission: %s' % bool(info.permissions() & QFile.WriteUser))
print('Py Writable: %s' % os.access(path, os.W_OK))
print('Py Permission: %s' % bool(os.stat(path).st_mode & stat.S_IWUSR))

tmp = QFile(path)
tmp.setPermissions(QFile.ReadUser)
print('')
print('Set Permissions: ReadUser')
print('')

info.refresh()
print('Qt Writable: %s' % info.isWritable())
print('Qt Permission: %s' % bool(info.permissions() & QFile.WriteUser))
print('Py Writable: %s' % os.access(path, os.W_OK))
print('Py Permission: %s' % bool(os.stat(path).st_mode & stat.S_IWUSR))

tmp.setPermissions(QFile.WriteUser)
print('')
print('Removed: %s' % tmp.remove())
对我来说,在Linux和WinXp上,我得到的结果如下:

File: /tmp/qt_temp.TJ1535

Qt Writable: True
Qt Permission: True
Py Writable: True
Py Permission: True

Set Permissions: ReadUser

Qt Writable: False
Qt Permission: False
Py Writable: False
Py Permission: False

Removed: True

See@ismail可能重复您能告诉我为什么您认为它是重复的吗?我认为QFile::isWritable实际上是QIODevice::isWritable在您的设置中总是返回false。QIODevice::iswriteable)返回文件是否为/opened/进行写入,但由于您没有打开()任何内容,它将始终返回false@FrankOsterfeld谢谢,这是一个非常有趣的注释。我已经更新了我的问题。你认为这是测试我是否能写一个文件的好方法吗?看起来这是一个很好且彻底的答案!