2012-04-21 60 views
1

我想只编辑现有JSON文件中的一个值。如何编辑现有JSON文件中的值而不解析全部内容?

有没有办法做到这一点,而无需解析和重写整个文件? (我使用Jackson Streaming API来生成和解析文件,但我不确定Streaming API可以做到这一点)。

Example.json文件包含以下内容:给出

{ 
"id" : "20120421141411", 
"name" : "Example", 
"time_start" : "2012-04-21T14:14:14" 
} 

例子:我想从“示例”编辑“姓名”的值改为“其他名字”。

回答

0

不是我所知道的;无论是JSON级还是文件级 - 除非值的长度恰好相同,否则底层文件系统通常需要从更改点重写文件的其余部分。

您可以使用Streaming API读取和写入文件,在旅途中替换值;请参阅JsonGenerator.copyCurrentEvent(jp)以简化任务 - 它只是按照原样复制输入事件。对于除了替换特定值之外的所有内容,您可以调用它;和价值,可以拨打JsonGenerator.writeString()

+0

非常感谢你 – 2012-04-24 02:48:11

+0

我很困惑。这将它复制到发生器?什么是事件?我有类似的问题,需要修改json字符串,但我不能从你的答案中解决这个问题。 – simgineer 2013-02-01 23:52:38

+0

这是用于Jackson Streaming API,其中'JsonParser'用于将JSON读作一系列事件('JsonToken');和“JsonGenerator”将JSON内容编写为类似的事件。您可以简单地将解析器连接到生成器,并让它复制大部分事件;除了添加/删除/替换您想要修改的事件。 我注意到我忘记了上面的'JsonParser'示例;显然需要让发电机知道从哪里得到输入。 – StaxMan 2013-02-02 04:31:04

0

如果文件很小并且您要替换的输入值是唯一的“足够”,并且您可以快速打开,请使用apache commons-exec或其他内容:

bash$> echo '{ 
     "id" : "20120421141411", 
     "name" : "Example", 
     "time_start" : "2012-04-21T14:14:14" 
    }' | sed -e 's/Example/othername/' 

输出:

{ 
    "id" : "20120421141411", 
    "name" : "othername", 
    "time_start" : "2012-04-21T14:14:14" 
} 

使用cat file | sed ...,如果你知道文件的路径。

如果您真的想在原地编辑文件,只写入要更改的字节,只有当您正在写入的数据不会覆盖文件中的后续数据时才有可能。使用上述解决方案之一,你会好得多。

假设JSON文件很庞大(> 1GB?),那么这种技术是否有意义?不,你用一个大的JSON文件做什么?把它分开!但为了争辩... ...

你真的想这样做,所以你钩入JSON解析器来跟踪文件中的字节偏移,并且能够将它绑定到表示JsonNode的对象上将被操纵。您可能最终会在此刻编写您自己的解析器; JSON语法是故意简单的。然后,你只需打开文件,跳到该偏移量,然后写入JsonNode数据......除非它会在它之后覆盖某些内容(是否在每个值之后用空间缓冲区预填充文件,以防万一?hmmm ......这听起来像是一个数据库问题)。在这种情况下,随着更大的值“向下推”其他所有内容,您将最终重写整个文件的其余部分。如果编辑总是接近文件结尾,则不是什么大问题。但如果它们是随机的,你的表现就注定了。你会瓶颈串行化写入。