How to use file streaming to write to a file without overwriting pre-existing data?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Moldor2

So,
I’m trying to create a database of JSON representing barcode numbers and related information, but when I call on my globally loaded script to write to a file it ends up overwriting anything that was already in the file.

extends "res://Scripts/item_class.gd"

var inventory := []
const userData := "res://localDatabase.txt"

func get_upc_data(barcode: String) -> Dictionary:
	var readData = File.new()
	
	if not readData.file_exists(userData):
		return {"Status": "File Doesn't Exist"}
	
	readData.open(userData, File.READ)
	
	while readData.get_position() < readData.get_len():
		var data = parse_json(readData.get_line())
		
		if data.get("Barcode") == barcode:
			readData.close()
			return {"Status": "Success", "Data": data}
	
	readData.close()
	return {"Status": "Not Found"}

func store_upc_data(data: Dictionary) -> void: #The function I'm having issues with
	var storeData = File.new()
	storeData.open(userData, File.WRITE)
	storeData.seek_end() #Puts the writing cursor at the end of the file
	storeData.store_line(to_json(data)) #Stores the dictionary as JSON data
	storeData.close()

As an unrelated question is it possible for me to read and write to a .JSON file instead of a .txt file? Also, if you require to see the item class that I’m extending, here it is.
extends Node

class_name Item

#### CLASS VARIABLES ####
var item := {
	"Barcode": "00000000",
	"Metadata": {
		"Name": "Name",
		"Description": "A short description of the item.",
		"Quantity": 1,
		"Product Category": "General",
		"Product Units": "ounces",
	}
}
#### SET DICTIONARY VARIABLES ####
func set_item(nBarcode: String, nName: String, nDescription: String, nQuantity: int, nCategory: String, nUnits: String):
	var meta := {
		"Name": nName,
		"Description": nDescription,
		"Quantity": nQuantity,
		"Product Category": nCategory,
		"Product Units": nUnits,
			}
	if item.has("Barcode") and item.has("Metadata"):
		item["Barcode"] = nBarcode
		item["Metadata"] = meta
func set_item_with_object(nItem: Item) -> void:
	item = nItem.item
func set_item_with_dict(nData: Dictionary) -> void:
	var nMeta = nData["Data"]["Metadata"]
	item["Barcode"] = nData["Data"]["Barcode"]
	item["Metadata"]["Name"] = nMeta.get("Name", "Name not found")
	item["Metadata"]["Description"] = nMeta.get("Description", "No description found")
	item["Metadata"]["Quantity"] = nMeta.get("Quantity", -1)
	item["Metadata"]["Product Category"] = nMeta.get("Product Category", "No category found")
	item["Metadata"]["Product Units"] = nMeta.get("Product Units", "No unit found")

### GET WHOLE ITEM ###
func get_item() -> Dictionary:
	return item
### SETTERS ###
func set_name(nName: String) -> void:
	item["Metadata"]["Name"] = nName
func set_description(nDescript: String) -> void:
	item["Metadata"]["Description"] = nDescript
func set_quantity(nQuant: int) -> void:
	item["Metadata"]["Quantity"] = nQuant
func set_category(nCategory: String) -> void:
	item["Metadata"]["Product Category"] = nCategory
func set_units(nUnits: String) -> void:
	item["Metadata"]["Product Units"] = nUnits
func set_barcode(nBarcode: String) -> void:
	item["Barcode"] = nBarcode
### GETTERS ###
func get_name() -> String:
	return item["Metadata"]["Name"]
func get_description() -> String:
	return item["Metadata"]["Description"]
func get_quantity() -> int:
	return item["Metadata"]["Quantity"]
func get_category() -> String:
	return item["Metadata"]["Product Category"]
func get_units() -> String:
	return item["Metadata"]["Product Units"]
func get_barcode() -> String:
	return item["Barcode"]

Thank you for any help you may have!

:bust_in_silhouette: Reply From: jgodfrey

The reason the file is being overwritten is that you’re opening it in WRITE mode here:

storeData.open(userData, File.WRITE)

According to the docs, WRITE truncates the file if it exists (so, removes the data). Looking at that doc page, the only WRITE-enabled mode that doesn’t truncate the file is READ_WRITE, so you’ll want to open the file in that mode.

However, (again according to the docs), opening it that way leaves the cursor at the beginning of the file, so you’ll still overwrite existing contents. To avoid that, you need to move the cursor to the end of the file before adding additional content. To do that, you can use:

seek_end()

After that, any content you add will be inserted at the end of the file. You could optionally insert an additional newline character after the seek_end() if you want/need the new content to start on the next line.

Regarding your second question (write a JSON file instead of a text file). I’m not sure I follow. A JSON file is just a text file with special content (and, I guess a .json extension). There’s nothing preventing you from doing that.