2

I have a .json file who handles the user's roles and I have wrote a Repository who's responsible of adding/removing roles to users. The pb is that when I modify the file I want to be sure that no one access it except me.

Here's (roughly) the code I use:

using (var fileStream = new FileStream(_rolesFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
using (var streamReader = new StreamReader(fileStream))
using (var streamWriter = new StreamWriter(fileStream))
{
    var oldContent = streamReader.ReadToEnd();
    var contentObject = Deserialize(oldContent);

    Modify(contentObject)

    var newContent = Serialize(contentObject);

    fileStream.Seek(0, SeekOrigin.Begin);
    streamWriter.Write(newContent);
}

The pb with this solution is that if newContent is a string shorter that oldContent some characters will be remaining in the file.

A solution I found is to add the following code:

using (var fileStream = new FileStream(_rolesFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
using (var streamReader = new StreamReader(fileStream))
using (var streamWriter = new StreamWriter(fileStream))
{
    //...

    var newContent = Serialize(contentObject);
    var endPosition = fileStream.Position;

    fileStream.Seek(0, SeekOrigin.Begin);
    streamWriter.Write(newContent);
    streamWriter.Flush();

    while (fileStream.Position < endPosition)
    {
        streamWriter.WriteLine();
        streamWriter.Flush();
    }
}

It works well but does not look very clean to me. Are there any better solution who ensure that I keep the control of the file ?

Thanks in advance, Thomas

2
  • I wouldn't say it is not clean. I think this code is quiet good. But if you want another solution, you can delete the file and create a new one with the same name. Then you are sure that only your text is in the file. Commented Oct 8, 2018 at 9:26
  • 1
    @Presi - delete/create can be "racy" since there's no way to keep a "lock" on the name between those two steps. Truncating all/part of a file is a well known operation and the "challenge" is working out how it's exposed in .NET. Commented Oct 9, 2018 at 8:13

1 Answer 1

1

You can do fileStream.SetLength(fileStream.Position) to truncate the remaining part of the file. This assumes that the FileStream is left correctly positioned by the StreamWriter after use, but that's an assumption your current code seems to be making too.

(This is a safer assumption than the corresponding usage of StreamReader where internal buffering may mean that the underlying stream's position is further advanced than the latest data returned by a call to a Read method)

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks ! Would that be the final code: fileStream.Seek(0, SeekOrigin.Begin); streamWriter.Write(newContent); streamWriter.Flush(); fileStream.SetLength(fileStream.Position); ?
May it be simplified to this code: fileStream.Seek(0, SeekOrigin.Begin); fileStream.SetLength(0); streamWriter.Write(newContent); ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.