为什么改成w+模式同时读写文件会导致读取失败?
Why does changing to `w+` mode for simultaneous reading from and writing to a file cause the read to fail?
我正在 Python 中编写代码,需要通过 RFID 标签注册用户并将该记录写入文件。
我设法编写了一个运行良好的函数:
def register_user(self, rfid):
with open(self._RECORDS_FILE_PATH, 'r') as infile:
recordsData = json.load(infile)
with open(self._RECORDS_FILE_PATH, 'w+') as outfile:
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
json.dump(recordsData, outfile)
但是我想尽量优化代码,减少行数。因此,我决定使用 w+
因为它应该可以同时读取和写入文件。
这是“优化”代码:
def register_user(self, rfid):
with open(self._RECORDS_FILE_PATH, 'w+') as file:
recordsData = json.load(file)
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
json.dump(recordsData, file)
“优化”代码不工作,并给出此错误:
Traceback (most recent call last):
File "/home/pi/accessControl/accessControlClasses/userInfoApi.py", line 57, in register_user_offline
recordsData = json.load(outfile)
File "/usr/lib/python2.7/json/__init__.py", line 291, in load
**kw)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
保存记录的文件:
{"recordsList": []}
谁能告诉我为什么会这样?
在 w+
模式下打开文件会截断它,因此一旦您尝试打开文件,就没有什么可读的了。此模式旨在让您在打开文件后返回并阅读您写的内容。
由于您必须读取该文件,因此需要以 r
模式打开它。由于您稍后想要替换全部内容,因此您必须截断它并以 w
模式打开它。所以,请继续使用您的原始版本!
正如 Thierry 所说,w+
截断文件——删除数据——所以有 none 可以读取。
用other read/write方式打开文件,r+
-- handle设置为文件开头,添加一个f.seek(0)
并且您的代码将正常工作。
with open(self._RECORDS_FILE_PATH, 'r+') as f:
recordsData = json.load(f)
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
f.seek(0) # go back to beginning of file
json.dump(recordsData, f)
我正在 Python 中编写代码,需要通过 RFID 标签注册用户并将该记录写入文件。
我设法编写了一个运行良好的函数:
def register_user(self, rfid):
with open(self._RECORDS_FILE_PATH, 'r') as infile:
recordsData = json.load(infile)
with open(self._RECORDS_FILE_PATH, 'w+') as outfile:
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
json.dump(recordsData, outfile)
但是我想尽量优化代码,减少行数。因此,我决定使用 w+
因为它应该可以同时读取和写入文件。
这是“优化”代码:
def register_user(self, rfid):
with open(self._RECORDS_FILE_PATH, 'w+') as file:
recordsData = json.load(file)
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
json.dump(recordsData, file)
“优化”代码不工作,并给出此错误:
Traceback (most recent call last):
File "/home/pi/accessControl/accessControlClasses/userInfoApi.py", line 57, in register_user_offline
recordsData = json.load(outfile)
File "/usr/lib/python2.7/json/__init__.py", line 291, in load
**kw)
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
保存记录的文件:
{"recordsList": []}
谁能告诉我为什么会这样?
在 w+
模式下打开文件会截断它,因此一旦您尝试打开文件,就没有什么可读的了。此模式旨在让您在打开文件后返回并阅读您写的内容。
由于您必须读取该文件,因此需要以 r
模式打开它。由于您稍后想要替换全部内容,因此您必须截断它并以 w
模式打开它。所以,请继续使用您的原始版本!
正如 Thierry 所说,w+
截断文件——删除数据——所以有 none 可以读取。
用other read/write方式打开文件,r+
-- handle设置为文件开头,添加一个f.seek(0)
并且您的代码将正常工作。
with open(self._RECORDS_FILE_PATH, 'r+') as f:
recordsData = json.load(f)
newRecord = {
"timestamp": int(round(time.time() * 1000)),
"rfid": rfid
}
recordsData["recordsList"].insert(0, newRecord)
f.seek(0) # go back to beginning of file
json.dump(recordsData, f)