File IO - Sharing violation

Anyone know why the code below would return a sharing violation and how to fix it?
The file gets created before the exception is thrown but the data doesn’t get written to it.
Thanks

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.UI;

public class SaveSystem : MonoBehaviour {

    public Text NewGameFilenameText;

    public void StartNew () {

        Player.player DataToWrite = new Player.player();

        string NewGameFilename = Convert.ToString(NewGameFilenameText.text);

        DataToWrite.filename = NewGameFilename;
        DataToWrite.health = 100;
        DataToWrite.x_coord = 0;
        DataToWrite.y_coord = 0;
        DataToWrite.z_coord = 0;

        string path = Application.persistentDataPath + "/sav/" + NewGameFilename + ".json";

        if (File.Exists(path))
        {
            Debug.Log("Cannot overwrite save file");
        }

        else
        {
            FileStream stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.Write);

            string json = JsonUtility.ToJson(DataToWrite, true);

            using (stream)
            {
                File.WriteAllText(path, json);
            }

        }
    }
}

On what platform? what exactly is the error?

It is recommended to create the filestream in the using statement instead of passing a reference.

You shouldn’t have to use the stream. File.WriteAllText should handle things for you.

2 Likes

That worked, thank you.

In case you’re interested, the sharing violation was occurring because you have an open stream on the file when you call File.WriteAllText. File.WriteAllText does not use the stream you have created, instead opening a new one.

Your stream is configured to allow other writers since you used FileShare.Write so it looks like another writer might have access. However, per the documentation, File.WriteAllText attempts to create the file, or recreate it if it already exists. This means it was trying to delete and recreate the file which had the open stream. Thus the sharing violation.

File.WriteAllText looks perfectly good for your scenario, though if you want more fine tuned control – to append data for instance – you will have to revert to using streams, like so:

var json = JsonUtility.ToJson(DataToWrite, true);
using(var stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write, FileShare.Write))
using (var writer = new StreamWriter(stream))
{
  writer.Write(json);
}
3 Likes

There is also an AppendAllText option https://docs.microsoft.com/en-us/dotnet/api/system.io.file.appendalltext?view=netframework-4.7.2

2 Likes

Very good point, the framework is filled with convenience methods.
It still occasionally pays off to know how to work with streams however.

1 Like