Python - 更新文件中的JSON对象

时间:2015-02-14 14:46:34

标签: python json

我有一个(有效的)JSON文件包含JSON对象,每个对象占用一个文件行。这些JSON对象映射到Python dicts,并按数字ID按升序排列。

我正在编写一个接受三个参数的更新方法:(1)文件路径,(2)有序ID列表,以及(3)带有更新值的JSON对象属性的dict,并遍历文件(以r+模式打开),在ID列表中查找JSON对象,然后使用dict中的值更新对象属性,并将对象写回文件。

每个对象占用一行,并以逗号分隔。如果所需的ID在一行中,那么在写入文件之前,指针将向后移动线的长度到开头。但问题是新的对象线可能更长,在这种情况下它会覆盖该对象后面的另一个对象的线。

我只需要替换我感兴趣的行,但不要覆盖后续行。任何帮助将不胜感激。

以下是代码:

def update_JSON_file( self, file_path, obj_IDs, obj_props ):

    decoder = json.JSONDecoder()

    with io.open( file_path, 'r+', encoding='utf=8' ) as file:
        IDs_iter = iter( obj_IDs )
        for line in file:
            ID = IDs_iter.next()
            if str( ID ) in line:
                JSON_obj = decoder.raw_decode( line )[0]
                for key in props.keys():
                    JSON_obj[key] = props[key] 
                JSON_obj = json.dumps( JSON_obj, ensure_ascii=False )
                if '},\n' in line: JSON_obj += ',\n'
                JSON_obj = unicode( JSON_obj )
                file.seek( file.tell() - len( line ) )
                file.write( JSON_obj )

2 个答案:

答案 0 :(得分:1)

你无法做你想做的事,因为你只能通过外科手术替换文件中的固定长度记录。您无法使用更长或更短的内容替换该行,因为文件不会将数据存储为单独的行。

此外,您的代码没有考虑到在某些平台上(如在Windows上)文本文件中的行由两个字符分隔,在Python中可以表示为\r\n,但这些行结尾是翻译成单个字符\n。您的行长计算并未考虑到这一点。

您必须在该行之后重写所有内容。你最好使用数据库; sqlite3与Python捆绑在一起,看一下。

答案 1 :(得分:0)

def update_JSON_file( self, file_path, obj_IDs, props ):
    decoder = json.JSONDecoder()
    with io.open( file_path, 'r+', encoding='utf=8' ) as files:
        IDs_iter = iter( obj_IDs )
        fl = files.read().splitlines(True)
        ID = IDs_iter.next()
        for i,line in enumerate(fl):
            # ID = IDs_iter.next()
            # I think the 'ID' should be initialized out of the loop
            # and iterated only if the condition is true
            if str(ID) in line:
                JSON_obj = decoder.raw_decode(line)[0]
                for key in props.keys():
                    JSON_obj[key] = props[key] 
                JSON_obj = json.dumps( JSON_obj, ensure_ascii=False )
                if '},\n' in line: JSON_obj += ',\n'
                JSON_obj = unicode( JSON_obj )
                fl[i] = JSON_obj
                try:
                    ID = IDs_iter.next()
                except StopIteration:
                    break
        files.seek(0)
        files.write(''.join(fl))
        return True