简体   繁体   English

为什么更改为“w+”模式同时读取和写入文件会导致读取失败?

[英]Why does changing to `w+` mode for simultaneous reading from and writing to a file cause the read to fail?

I am writing code in Python which needs to register a user by RFID tag and write that record to a file.我在 Python 中编写代码,需要通过 RFID 标签注册用户并将该记录写入文件。

I managed to write a function which works perfectly fine:我设法编写了一个运行良好的 function:

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)

But I would like to optimise the code as much as possible and reduce the number of lines.但我想尽可能优化代码,减少行数。 Because of that, I decided to use w+ because it should enable reading from and writing to the file simultaneously.因此,我决定使用w+ ,因为它应该能够同时读取和写入文件。

This is the "optimised" code:这是“优化”的代码:

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)

The "optimised" code is not working and it is giving this error: “优化”代码不起作用,它给出了这个错误:

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

The file in which records will be saved:将保存记录的文件:

{"recordsList": []}

Can someone tell me why is this happening?有人能告诉我为什么会这样吗?

Opening the file in w+ mode truncates it, so there is nothing to read once you try to do it.w+模式打开文件会截断它,因此一旦您尝试这样做,就没有什么可读取的了。 This mode is meant to allow you to go back and read what you wrote after opening the file.此模式旨在让您返回 go 并阅读您在打开文件后写入的内容。

As you will have to read the file, you need to open it in r mode.由于您必须阅读该文件,因此您需要在r模式下打开它。 As you want to replace the whole content later, you will have to truncate it and open it in w mode.由于您想稍后替换整个内容,因此您必须截断它并以w模式打开它。 So, stay with your original version!所以,请继续使用您的原始版本!

As Thierry said, w+ truncates the file -- deletes the data -- so there is none to read.正如蒂埃里所说, w+会截断文件——删除数据——因此没有可读取的内容。

Open the file with the other read/write mode, r+ -- where the handle is set to the beginning of the file, and add an f.seek(0) and your code will work fine.使用另一种读/写模式打开文件, r+ -- 其中句柄设置为文件的开头,并添加一个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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM