Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,45 @@ public async Task When_InputStreamFlush()
}
}

[TestMethod]
public async Task When_OpenStreamForWriteAsync_On_New_File()
{
var rootFolder = await GetRootFolderAsync();
var fileName = GetRandomTextFileName();
var filePath = Path.Combine(rootFolder.Path, fileName);

try
{
// Ensure the file does not exist
if (File.Exists(filePath))
{
File.Delete(filePath);
}

// Get a reference to a file that doesn't exist yet
var storageFile = await StorageFile.GetFileFromPathAsync(filePath);

// This should not throw FileNotFoundException
using var stream = await storageFile.OpenStreamForWriteAsync();
using var writer = new StreamWriter(stream);
await writer.WriteAsync("Test content");
await writer.FlushAsync();

// Verify the file was created and contains the expected content
Assert.IsTrue(File.Exists(filePath), "File should have been created");
var content = await FileIO.ReadTextAsync(storageFile);
Assert.AreEqual("Test content", content);
}
finally
{
if (File.Exists(filePath))
{
File.Delete(filePath);
}
await CleanupRootFolderAsync();
}
}

private string GetRandomFolderName() => Guid.NewGuid().ToString();

private string GetRandomTextFileName() => Guid.NewGuid().ToString() + ".txt";
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UWP/Storage/StorageFile.Local.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public override Task<IRandomAccessStreamWithContentType> OpenAsync(CancellationT
=> Task.FromResult<IRandomAccessStreamWithContentType>(new RandomAccessStreamWithContentType(FileRandomAccessStream.CreateLocal(Path, ToFileAccess(accessMode), ToFileShare(options)), ContentType));

public override Task<Stream> OpenStreamAsync(CancellationToken ct, FileAccessMode accessMode, StorageOpenOptions options)
=> Task.FromResult<Stream>(File.Open(Path, FileMode.Open, ToFileAccess(accessMode), ToFileShare(options)));
=> Task.FromResult<Stream>(File.Open(Path, ToFileMode(accessMode), ToFileAccess(accessMode), ToFileShare(options)));

public override Task<StorageStreamTransaction> OpenTransactedWriteAsync(CancellationToken ct, StorageOpenOptions option)
=> Task.FromResult(new StorageStreamTransaction(Owner, ToFileShare(option)));
Expand Down
16 changes: 16 additions & 0 deletions src/Uno.UWP/Storage/StorageFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,22 @@ private static FileAccess ToFileAccess(FileAccessMode accessMode)
_ => throw new ArgumentOutOfRangeException(nameof(accessMode))
};

/// <summary>
/// Maps FileAccessMode to the appropriate FileMode for file operations.
/// </summary>
/// <param name="accessMode">The access mode requested for the file.</param>
/// <returns>
/// FileMode.Open for Read access (requires file to exist),
/// FileMode.OpenOrCreate for ReadWrite access (creates file if it doesn't exist).
/// </returns>
private static FileMode ToFileMode(FileAccessMode accessMode)
=> accessMode switch
{
FileAccessMode.Read => FileMode.Open,
FileAccessMode.ReadWrite => FileMode.OpenOrCreate,
_ => throw new ArgumentOutOfRangeException(nameof(accessMode))
};

private static FileShare ToFileShare(StorageOpenOptions options)
=> options switch
{
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UWP/Storage/StorageFile.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public override Task<IRandomAccessStreamWithContentType> OpenAsync(CancellationT

public override Task<Stream> OpenStreamAsync(CancellationToken ct, FileAccessMode accessMode, StorageOpenOptions options)
{
Func<Stream> streamBuilder = () => File.Open(Path, FileMode.Open, ToFileAccess(accessMode), ToFileShare(options));
Func<Stream> streamBuilder = () => File.Open(Path, ToFileMode(accessMode), ToFileAccess(accessMode), ToFileShare(options));
var streamWrapper = new SecurityScopeStreamWrapper(_nsUrl, streamBuilder);
return Task.FromResult<Stream>(streamWrapper);
}
Expand Down
Loading