Aellopos Aellopos - 20 days ago 9
JSON Question

UWP - writing to JSON without owerwrite data

I want to write data to JSON file, without overwriting them. I am using this code

Item test = new Item("test", 23);

try
{
var Folder = Windows.Storage.ApplicationData.Current.LocalFolder;
//var file = await Folder.CreateFileAsync("data.json", Windows.Storage.CreationCollisionOption.ReplaceExisting);
var file = await Folder.GetFileAsync("data.json");
var data = await file.OpenStreamForWriteAsync();

using (StreamWriter r = new StreamWriter(data))
{
var serelizedfile = JsonConvert.SerializeObject(test);
r.Write(serelizedfile);
}
}
catch (Exception a)
{
throw a;
}

Answer

Noticed that you're possibly using the Json.NET for serialization and deserialization the Json file. I think it's better to deserialize the list of Json object and you can operate on this list, then serialize the new list to Json and save into the file, not directly serialize one item and write it into the file.

For example, my Json file is like this:

[
    {"color":"red","value":"#f00"},
    {"color":"green","value":"#0f0"},
    {"color":"blue","value":"#00f"},
    {"color":"cyan","value":"#0ff"},
    {"color":"magenta","value":"#f0f"},
    {"color":"yellow","value":"#ff0"},
    {"color":"black","value":"#000"}
]

code for adding one item to this file:

if (file != null)
{
    using (var streamIn = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        DataReader reader = new DataReader(streamIn);
        await reader.LoadAsync((uint)streamIn.Size);
        var jsonInstring = reader.ReadString((uint)streamIn.Size);
        var JobjList = JsonConvert.DeserializeObject<List<JsonColor>>(jsonInstring);
        reader.Dispose();
        JobjList.Add(new JsonColor() { color = "pink", value = "#c0c" });
        JsonOutstring = JsonConvert.SerializeObject(JobjList);
    }
    using (var streamOut = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        DataWriter writer = new DataWriter(streamOut);
        writer.WriteString(JsonOutstring);
        await writer.StoreAsync();
        writer.DetachStream();
        writer.Dispose();
    }
}
else
{
}

My class object:

public class JsonColor
{
    public string color { get; set; }
    public string value { get; set; }
}

As you can see, I deserialized the Json file and get the List<JsonColor>, then I added one item new JsonColor() { color = "pink", value = "#c0c" } to this list, and finally serialized this new list and save it. So for your scenario, you can modify the Json file and my JsonColor class to fit your need.

Update:

private string JsonOutstring;

private async void Button_Click(object sender, RoutedEventArgs e)
{
    //create a json file, if the file is exit, then open it.
    var local = Windows.Storage.ApplicationData.Current.LocalFolder;
    var Jsonfile = await local.CreateFileAsync("test.json", Windows.Storage.CreationCollisionOption.OpenIfExists);
    if (Jsonfile != null)
    {
        ReadAndWriteJsonFile(Jsonfile);
    }
    else
    {
    }
}

public async void ReadAndWriteJsonFile(StorageFile file)
{
    using (var streamIn = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        DataReader reader = new DataReader(streamIn);
        await reader.LoadAsync((uint)streamIn.Size);
        var jsonInstring = reader.ReadString((uint)streamIn.Size);
        var JobjList = JsonConvert.DeserializeObject<List<JsonColor>>(jsonInstring);
        reader.Dispose();
        if (JobjList == null)
        {
            JobjList = new List<JsonColor>();
        }
        JobjList.Add(new JsonColor() { color = "pink", value = "#c0c" });
        JsonOutstring = JsonConvert.SerializeObject(JobjList);
    }
    using (var streamOut = await file.OpenAsync(FileAccessMode.ReadWrite))
    {
        DataWriter writer = new DataWriter(streamOut);
        writer.WriteString(JsonOutstring);
        await writer.StoreAsync();
        writer.DetachStream();
        writer.Dispose();
    }
}

public class JsonColor
{
    public string color { get; set; }
    public string value { get; set; }
}