【问题标题】:PyQt: QTemporaryFile - unable to read from filePyQt:QTemporaryFile - 无法从文件中读取
【发布时间】:2013-05-28 17:09:41
【问题描述】:

我无法从 QTemporaryFile 创建的临时文件中读取,也许你可以检查下面的代码...

>>> from PyQt4 import QtCore
>>> fileTemp = QtCore.QTemporaryFile()
>>> fileTemp.open()
True   #file is created
>>> fileTemp.fileName()
PyQt4.QtCore.QString(u'/tmp/qt_temp.TJ2302')
>>> fileTemp.writeData('foobar')
6L     #six bytes are written, great
>>> open(fileTemp.fileName(), 'r').read()
''     #but there is still nothing inside!
>>> fileTemp.size()
6L     #magically, by doing this 'foobar' appears in this tempFile...
       #the same effect gives e.g. fileTemp.readData(1000), but nothing is read
>>> open(fileTemp.fileName(), 'r').read()
'foobar'
>>> fileTemp.readData(1000)
''     #why...
>>> fileTemp.readAll()
PyQt4.QtCore.QByteArray('')
>>> fileTemp.readAll().size()
0      #why...

将不胜感激!

编辑

我已将 QTemporaryFile 扩展为按预期运行,但仍在寻找更干净的解决方案...

class MyTemporaryFile(QtCore.QTemporaryFile):
    def __init__(self, *argc, **argv):
        QtCore.QTemporaryFile.__init__(self, *argc, **argv)

    def write(self, data):
        f = open(self.fileName(), 'w')
        f.write(data)
        f.close()

    def read(self):
        f = open(self.fileName(), 'r')
        data = f.read()
        f.close()
        return data

【问题讨论】:

    标签: python pyqt pyqt4 temporary temporary-files


    【解决方案1】:

    如果您想强制操作系统将数据写入文件,您应该始终flush():

    In [10]: from PyQt4 import QtCore
    
    In [11]: fileTemp = QtCore.QTemporaryFile()
    
    In [12]: fileTemp.open()
    Out[12]: True
    
    In [13]: fileTemp.fileName()
    Out[13]: PyQt4.QtCore.QString(u'/tmp/qt_temp.XM5599')
    
    In [14]: fileTemp.writeData('foobar')
    Out[14]: 6L
    
    In [15]: with open(fileTemp.fileName(), 'r') as f:
       ....:     print(f.read())
       ....:     
    
    
    In [16]: fileTemp.flush()
    Out[16]: True
    
    In [17]: with open(fileTemp.fileName(), 'r') as f:
        print(f.read())
       ....:     
    foobar
    

    可能对size() 的调用隐式强制操作系统刷新,因此您观察到的行为。

    【讨论】:

    • 谢谢,所以我现在知道如何正确写入临时文件...但是我如何从中读取呢? tempFile.read(1000) 返回空字符串, tempFile.readAll() 返回空 QByteArray。当然我总是可以做 open(fileTemp.fileName(), 'r'),但是为什么提到的这两个不起作用?
    • @user2220568 你必须认为每个文件都有一个指向当前文件位置的指针。当您创建一个新的临时文件并写入'foobar' 时,指针将移动到写入文件的数据的末尾。 read() 从当前位置开始读取数据,因此是空字符串(因为在 'foobar' 之后您的文件为空)。如果要设置当前位置,可以使用seek 方法。特别是tempFile.seek(0) 会将当前位置设置在文件的开头。
    • 谢谢!但仍然缺少一些东西。在 f.flush() 和 f.seek(0) 之后,f.readAll() 返回了空的 QByteArray。但是 f.flush() f.seek(1) f.seek(0) 完成了这项工作......
    • 我刚刚检查了上面提到的这种行为只出现在windows上,在linux上调用一次seek就足够了。奇怪的。我将在答案中附加 Windows 代码...
    • @user2220568 不知道为什么会这样。
    【解决方案2】:

    所以正确的做法是:

    >>> from PyQt4 import QtCore
    >>> f = QtCore.QTemporaryFile()
    >>> f.open()
    True
    >>> f.writeData('foobar')
    6L
    >>> f.flush()
    True
    >>> f.seek(0)
    True
    >>> f.readAll()
    PyQt4.QtCore.QByteArray('foobar')
    

    但它只能在 linux 上运行...在 windows 上我必须这样做:

    >>> ================================ RESTART ================================
    >>> from PyQt4 import QtCore
    >>> f = QtCore.QTemporaryFile()
    >>> f.open()
    True
    >>> f.writeData('foobar')
    6L
    >>> f.flush()
    True
    >>> f.seek(0)
    True
    >>> f.readAll()
    PyQt4.QtCore.QByteArray()
    >>> ================================ RESTART ================================
    >>> from PyQt4 import QtCore
    >>> f = QtCore.QTemporaryFile()
    >>> f.open()
    True
    >>> f.writeData('foobar')
    6L
    >>> f.flush()
    True
    >>> f.seek(1)
    True
    >>> f.seek(0)
    True
    >>> f.readAll()
    PyQt4.QtCore.QByteArray('foobar')
    

    也许让这更清楚:

    from PyQt4 import QtCore
    
    class MyTemporaryFile(QtCore.QTemporaryFile):
        def __init__(self, *argc, **argv):
            QtCore.QTemporaryFile.__init__(self, *argc, **argv)
            self.open()
    
        def write(self, data):
            self.writeData(data)
            self.flush()
    
        def read(self):
            #self.seek(1)   #on windows it works only with this line uncommented
            self.seek(0)
            return self.readAll()
    

    【讨论】:

      猜你喜欢
      • 2020-04-07
      • 1970-01-01
      • 2017-09-06
      • 2021-08-27
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多