shridhar kapshikar shridhar kapshikar - 3 months ago 30
Python Question

Append the data to existing json file

I have an existing JSON file and trying to add string into file. But as soon as I write a JSON file the new line characters do disappear in the JSON file and format gets changed.

Below is the code:

#!/usr/bin/python
import json

userinput = raw_input('Enter the name of a file a you want to read: ')
with open(userinput) as json_data:
s = json_data.read()
data = json.loads(s)
print data['classes']
json_data.close()


class_add = raw_input('Enter the name of a class a you want to add: ')
if class_add in data['classes']:
print "Class %s already exists, doing nothing." % class_add
else:
data['classes'].append(class_add)
print json.dumps(data)
print data['classes']
with open(userinput, 'w') as json_data:
json_data.write(json.dumps(data))
json_data.close()





One more import thing here is, that the formatting of the JSON file. So by default we will be having the file in the below formatting.

# cat test.json
{
"selinux_mode": "enforcing",
"cis_manages_auditd_service": true,
"classes": [ "basic", "admin", "lvm"]
}
#


But once we add the class it becomes the following.

# cat test.json
{"cis_manages_auditd_service": true, "classes": [ "basic", "admin", "lvm"], "selinux_mode": "enforcing"}


Is there any way that I can keep the JSON whitespace and new line character as it is without changing anything.

Answer

JSON doesn't need a particular layout, but for slightly less bad human readability you can supply indent=2

import sys
import json

userinput = raw_input('Enter the name of a file a you want to read: ')
with open(userinput) as json_data:
    data = json.load(json_data)
    print(data['classes'])


class_add = raw_input('Enter the name of a class a you want to add: ')
if class_add in data['classes']:
    print("Class {} already exists, doing nothing.".format(class_add))
else:
    data['classes'].append(class_add)
    json.dump(data, sys.stdout, indent=2)
    print(data['classes'])
    with open(userinput, 'w') as json_data:
        json.dump(data, json_data, indent=2)

Please note that if you are using the with statement to open a file, you should not close it explicitly (that is done at the end of the block, whether there is an exception or not).

If you are writing to a file, instead of processing the JSON as string, you should also refrain from using json.dumps(data) and use json.dump(data, file_pointer) instead. The same holds for json.loads() and json.load().