JSONDecodeError: Expecting value: line 1 when using valid json

JSONDecodeError: Expecting value: line 1 when using valid json

我一直在为我的脚本使用看门狗和 json,我在其中监视要创建的文件和 json 来读取已创建的文件。该脚本很简单:

import watchdog.events
import watchdog.observers
import json

def on_created(self, event):

    with open(event.src_path, 'r') as f:
        print(f.read())
        data = json.load(f)


def main(self):
    observer = watchdog.observers.Observer()
    observer.schedule(NotificationsEvent(), path=os.path.split(self.notificationFlag)[0], recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

基本上当有一个路径为 json 的新文件创建时。阅读它然后加载为 json 并且它工作得很好但有时它会抛出一个错误说:

预期值:第 1 行第 1 列(字符 0)

当我检查 f.read() 的打印时 returns 我:

{
    "delay": 0,
    "image": "https://secure-images.nike.com/is/image/DotCom/CK9388_484",
    "keyword": false,
    "link": "https://www.nike.com/se/t/traningssko-metcon-6-78352H/CK9388-484",
    "name": "NIKE METCON 6",
    "price": "1337",
    "shortcut": [
        "[Checkout](https://www.nike.com/se/cart)"
    ],
    "sizes": [],
    "sku": "CK9388-100",
    "store": "Nike",
    "text": "New!",
    "webhook": "nike"
}

我已经使用 https://jsonlint.com/ 来查看它是否有效并且它是有效的,但有时我确实会收到错误消息。这是我 50 次中的 1 次。我无法再次重现错误,这种情况很少发生,但确实发生了。

我不知道,我正在忘记可能导致它的问题:(

感谢所有帮助!

f.read() 正在读取整个文件,因此 json.load() 没有任何内容可供读取。

你应该读入一个变量然后使用json.loads()..

def on_created(self, event):

    with open(event.src_path, 'r') as f:
        js = f.read()
        print(js)
        data = json.loads(js)

或者您可以在它们之间倒回文件。

def on_created(self, event):

    with open(event.src_path, 'r') as f:
        print(f.read())
        f.seek(0)
        data = json.load(f)

如果您在没有 print(f.read()) 行的情况下收到错误,那么问题是您的代码是 运行 在编写器完成写入文件之前。

并没有真正可靠的方法来判断编写器何时完成写入文件。最好的解决方案是让它以原子方式创建文件。它应该将数据写入不同的文件,然后将文件重命名为您的代码正在监视的文件。

您可以使用 try/except

的循环
def on_created(self, event):
    for _ in range(5): // limit the number of retries
        try:
            with open(event.src_path, 'r') as f:
                data = json.load(f)
            break
        except JsonDecodeError:
            print("JSON load error, retrying")
            os.sleep(1) // allow time for writer to finish