3
votes

I am writing a Windows Phone 8.1 (WINRT XAML) app.

In method 1, I am opening a StorageFile, and in method 2 I am writing on the same file. But it shows error while writing to the file.

  1. How to close this file after opening and reading contents?
  2. Then how to close this file again after writing to it in method 2?

    private async Task<bool> Method1(int workOutID)
    {
        string filename = "WorkoutOfflineDataFile.txt";
        StorageFolder LocalStorageFolderObject = ApplicationData.Current.LocalFolder;
        StorageFile StorageFileObject = await LocalStorageFolderObject.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
        string JSONFromFile = await FileIO.ReadTextAsync(StorageFileObject);
    }
    
    private async void Method2()
    {
        string filename = "WorkoutOfflineDataFile.txt";
        StorageFolder LocalStorageFolderObject = ApplicationData.Current.LocalFolder;
        StorageFile StorageFileObject = await LocalStorageFolderObject.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
        await FileIO.WriteTextAsync(StorageFileObject, JSonData_ToSave);
    }
    

ERROR:

Exception thrown: 'System.UnauthorizedAccessException' in mscorlib.ni.dll

Additional information: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

3
Please paste your code into code blocks. Right now its unreadable.Festyk
@Festyk, Please check nowAtif Shabeer
How are you calling these methods?Kristian Vukusic
@ Kristian Vukusic , Page.Loaded executes method1, then when all tasks are done, method 2 is executedAtif Shabeer
Method2 is not a Task so if you are firing it from code and awaiting it, the program will not wait for finish it.Festyk

3 Answers

2
votes

The code seems right, I think the exception is thrown by something else.

Anyway, if you want to be sure that your file and stream are closed after the read/write operations, you can use disposable way:

private async Task<bool> Method1(int workOutID)
{
    string filename = "WorkoutOfflineDataFile.txt";
    StorageFolder LocalStorageFolderObject = ApplicationData.Current.LocalFolder;
    StorageFile StorageFileObject = await LocalStorageFolderObject.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
    using (var stream = await StorageFileObject.OpenStreamForReadAsync())
    {
        using (var reader = new StreamReader(stream))
        {
            string JSONFromFile = reader.ReadToEnd();
        }
    }
}

private async void Method2()
{
    string filename = "WorkoutOfflineDataFile.txt";
    StorageFolder LocalStorageFolderObject = ApplicationData.Current.LocalFolder;
    StorageFile StorageFileObject = await LocalStorageFolderObject.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
    using (var stream = await StorageFileObject.OpenStreamForWriteAsync())
    {
        using (var writer = new StreamWriter(stream))
        {
            writer.Write(JSonData_ToSave);
        }
    }
}
0
votes

Does Festyk's solution work? Maybe just try to use:

StorageFile StorageFileObject = await LocalStorageFolderObject.GetFileAsync(filename);

In your second method, if you're sure file already exists - remember, otherwise it will throw an exception.

0
votes

You're Locking the file in method1()

private async Task<bool> Method1(int workOutID)
{
    string filename = "WorkoutOfflineDataFile.txt";
    StorageFolder LocalStorageFolderObject = ApplicationData.Current.LocalFolder;
    StorageFile StorageFileObject = await LocalStorageFolderObject.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
    string JSONFromFile = await FileIO.ReadTextAsync(StorageFileObject);
}

when you're trying to access WorkoutOfflineDataFile.txt you're actually locking this file, so no other thread can touch it until it's closed.

Luca's answer seems to be good and safe. Try using it.