C# 在 StorageFile.DeleteAsync 后创建文件失败并显示 0x80070005 E_ACCESSDENIED

C# Create file after StorageFile.DeleteAsync fails with 0x80070005 E_ACCESSDENIED

我找到了一个与我的相似的question,但不幸的是它没有答案。

我在 C# 中使用 StorageFile class 来重复创建、写入和删除文件。在我的第二次迭代中,它无法创建文件,返回拒绝访问错误。

这是我在 Visual Studio 2015 年整理的一个简单的单元测试来演示问题:

[TestMethod]
public async Task DeleteTest()
{
    StorageFolder folder = Windows.Storage.ApplicationData.Current.LocalFolder;
    byte[] array = System.Text.Encoding.ASCII.GetBytes("Test data");

    int i = 1, max = 20;
    string phase = "not started";
    try
    {
        do
        {
            // create file
            phase = "creating";
            StorageFile file = await folder.CreateFileAsync("test" /*,CreationCollisionOption.GenerateUniqueName*/);

            // write data to the file
            phase = "opening";
            System.IO.Stream stream = await file.OpenStreamForWriteAsync();

            phase = "writing";
            await stream.WriteAsync(array, 0, array.Length);

            phase = "flushing";
            await stream.FlushAsync();

            // delete file
            phase = "deleting";
            await file.DeleteAsync();
        } while (++i <= max);
    }
    catch(Exception e)
    {
        Assert.Fail("While '{0}' on iteration {1}: {2}", phase, i, e.Message);
    }
}

上面的断言触发,报告:

While 'creating' on iteration 2: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

如果有人能告诉我我做错了什么,我将不胜感激。我对此束手无策。

某些库功能(例如文件流访问)使用非托管资源,必须在销毁对象句柄之前正确清理这些资源.这避免了诸如即使在程序完成执行后文件在后台打开并防止它们被修改等情况。

对于 System.IO 和相关功能,Microsoft recommends 您调用的 Dispose()Close() 方法正是这样做的。在您的情况下,很可能无法成功删除该文件,因为它是通过 Stream 对象打开的。

因此,在 Stream 上的 Flush() 之后添加 Dispose() 应该可以解决问题。

注意:Dispose() 自动调用 Flush(),因此显式调用是多余的。