我的程序有时会在 json 文件的数据末尾写一个额外的 ] 或 ?

Posted

技术标签:

【中文标题】我的程序有时会在 json 文件的数据末尾写一个额外的 ] 或 ?【英文标题】:My program sometimes writes an extra ] or at the end of data in json file?我的程序有时会在 json 文件的数据末尾写一个额外的 ] 或 ? 【发布时间】:2017-09-25 12:16:51 【问题描述】:

我为自己编写了一个笔记工具作为我的第一个程序。它实际上在大多数情况下工作得非常好,但是有时程序会在 listdict 的末尾写一个额外的 ] 存储在所述 json 文件中。

这种情况不会经常发生,我认为只有在我编写新代码行或更改读取/写入所述文件的现有行时才会发生这种情况。我不是 100% 确定,但这就是它的样子。

例如,我有一个 list 存储在一个文件中,我使用 indent="" 标志来确保它在写入文件时对我来说更具可读性,如果我不得不编辑所述文件。有时在更改某些代码或添加代码后运行我的程序时,我会收到一个错误,指出文件中包含“额外数据”。 错误看起来像这样:

    raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 6 column 2 (char 5791)

错误的原因是这样的:

[
"Help",
"DataTypes",
"test",
"Variables",
]] # the error would be cause by this extra ] at the end of the list

我不明白的是为什么程序有时会在我的 json 文件中的数据末尾添加额外的 ] 或 ?

当我打开文件或转储到文件时,我做错了什么吗?

以下是我用于打开文件和转储到文件的一些代码部分:

path = "./NotesKeys/"
notebook = dict()
currentWorkingLib = ""
currentWorkingKeys = ""
#~~~~~~~~~~~~~~~~~~~< USE TO open all files in Directory >~~~~~~~~~~~~~~~~~~~
with open("%s%s"%(path,"list_of_all_filenames"), "r") as listall:
    list_of_all_filenames = json.load(listall)

def openAllFiles(event=None):
    global path
    for filename in os.listdir(path):
        with open(path+filename, "r+") as f:
            notebook[filename] = json.load(f)
openAllFiles()

这就是我如何更新文件中的数据。只需忽略e1Current, e1allcase, e2Current,它们用于在存储笔记的字典中保持用户输入文件名(dict 键)小写的格式,并保持用户为显示列表输入的大小写。这应该与文件读写问题无关。:

编辑:根据评论者的要求删除了不相关的代码。

#~~~~~~~~~~~~~~~~~~~< UPDATE selected_notes! >~~~~~~~~~~~~~~~~~~~

            dict_to_be_updated = notebook[currentWorkingLib]
            dict_to_be_updated[e1Current] = e2Current
            with open("%s%s"%(path,currentWorkingLib),"r+") as working_temp_var:
                json.dump(dict_to_be_updated, working_temp_var, indent = "")

我知道如何打开文件和使用数据以及如何将数据转储到所述文件并根据新转储的数据更新程序变量中加载的内容。

在这个过程中我是否遗漏了一些重要的东西?我应该做些什么来确保 json 文件中的数据完整性吗?

【问题讨论】:

@TankorSmash 基本上是MCVE。 @TankorSmash 删除了不相关的东西 【参考方案1】:

您正在以读写模式打开文件,r+:

with open("%s%s"%(path,currentWorkingLib),"r+") as working_temp_var:

这意味着您将写入一个其中已经有数据的文件,有时现有数据比您现在写入文件的数据更长 .这意味着您最终会得到一些尾随数据。

您可以通过将较短的演示字符串写入文件,然后使用r+less 数据写入同一文件,然后再次读取来看到这一点:

>>> with open('/tmp/demo', 'w') as init:
...     init.write('The quick brown fox jumps over the lazy dog\n')
...
44
>>> with open('/tmp/demo', 'r+') as readwrite:
...     readwrite.write("Monty Python's flying circus\n")
...
29
>>> with open('/tmp/demo', 'r') as result:
...     print(result.read())
...
Monty Python's flying circus
r the lazy dog

不要这样做。使用w写模式,这样文件首先被截断:

with open("%s%s"%(path,currentWorkingLib), "w") as working_temp_var:

这可确保在您编写新的 JSON 文档之前将文件缩减为 0。

【讨论】:

啊哈,这很有道理。我会试试的。我真的无法测试它,因为我不确定是什么触发了问题,因为它感觉有点随机,但它看起来确实是正确的解决方案。谢谢您的意见。这应该可以解决问题。 :D @SierrMountainTech:触发的是您首先编写一个 JSON 对象,然后再编写一个包含较少数据的 JSON 对象。从外观上看是一个字符。如果您知道要放入对象中的数据量,应该很容易触发;多投入,少投入。 这是有道理的。当我浏览笔记时,某些文件可能会不时删除空格。然而,一些正在写入的数据是对现有数据(主要是 fly_names 列表)的刷新,并且只会变得更长。它永远不会变短。我还没有在我的程序中创建删除文件的功能。有时该列表也会遇到同样的问题。

以上是关于我的程序有时会在 json 文件的数据末尾写一个额外的 ] 或 ?的主要内容,如果未能解决你的问题,请参考以下文章

Zip文件破解器python 3只会在文本文件末尾使用密码

使用 PigStorage 加载缺少最后一个字段的数据

如果你写程序不愿写注释,只有一个原因

如何设置下载数据的时间限制(来自json数据库)Swift 2

那些写程序不想写注释的原因,有趣~

Swift 将 JSON 转换为字典数组问题 错误代码 3840(末尾有垃圾)