diff --git a/src/Foundatio.DataProtection/FoundatioStorageXmlRepository.cs b/src/Foundatio.DataProtection/FoundatioStorageXmlRepository.cs index fa2871c7..2b79c3d9 100644 --- a/src/Foundatio.DataProtection/FoundatioStorageXmlRepository.cs +++ b/src/Foundatio.DataProtection/FoundatioStorageXmlRepository.cs @@ -51,12 +51,12 @@ private async Task> GetAllElementsAsync() return new XElement[0]; } - _logger.LogTrace("Found {FileCount} elements.", files.Count); + _logger.LogTrace("Found {FileCount} elements", files.Count); var elements = new List(files.Count); foreach (var file in files) { _logger.LogTrace("Loading element: {File}", file.Path); - using (var stream = await _storage.GetFileStreamAsync(file.Path).AnyContext()) + using (var stream = await _storage.GetFileStreamAsync(file.Path, StreamMode.Read).AnyContext()) { elements.Add(XElement.Load(stream)); } diff --git a/src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs b/src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs index ca531b0d..ea3294a0 100644 --- a/src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs +++ b/src/Foundatio.TestHarness/Storage/FileStorageTestsBase.cs @@ -257,21 +257,22 @@ public virtual async Task CanSaveFilesAsync() string readmeFile = GetTestFilePath(); using (storage) { - Assert.False(await storage.ExistsAsync("Foundatio.Tests.csproj")); + const string path = "cansavefiles.txt"; + Assert.False(await storage.ExistsAsync(path)); await using (var stream = new NonSeekableStream(File.Open(readmeFile, FileMode.Open, FileAccess.Read))) { - bool result = await storage.SaveFileAsync("Foundatio.Tests.csproj", stream); + bool result = await storage.SaveFileAsync(path, stream); Assert.True(result); } Assert.Single(await storage.GetFileListAsync()); - Assert.True(await storage.ExistsAsync("Foundatio.Tests.csproj")); + Assert.True(await storage.ExistsAsync(path)); - await using (var stream = await storage.GetFileStreamAsync("Foundatio.Tests.csproj")) + await using (var stream = await storage.GetFileStreamAsync(path, StreamMode.Read)) { string result = await new StreamReader(stream).ReadToEndAsync(); - Assert.Equal(File.ReadAllText(readmeFile), result); + Assert.Equal(await File.ReadAllTextAsync(readmeFile), result); } } } diff --git a/src/Foundatio/Storage/FolderFileStorage.cs b/src/Foundatio/Storage/FolderFileStorage.cs index 6428e7dd..caf54dc3 100644 --- a/src/Foundatio/Storage/FolderFileStorage.cs +++ b/src/Foundatio/Storage/FolderFileStorage.cs @@ -52,51 +52,16 @@ public Task GetFileStreamAsync(string path, CancellationToken cancellati => GetFileStreamAsync(path, StreamMode.Read, cancellationToken); public Task GetFileStreamAsync(string path, StreamMode streamMode, CancellationToken cancellationToken = default) - { - var stream = streamMode switch - { - StreamMode.Read => GetFileStreamAsync(path, FileAccess.Read), - StreamMode.Write => GetFileStreamAsync(path, FileAccess.Write), - _ => throw new NotSupportedException($"Stream mode {streamMode} is not supported."), - }; - - return Task.FromResult(stream); - } - - public Stream GetFileStreamAsync(string path, FileAccess fileAccess) { if (String.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); string normalizedPath = path.NormalizePath(); string fullPath = Path.Combine(Folder, normalizedPath); - if (fileAccess != FileAccess.Read) - { - CreateFileStream(fullPath).Dispose(); - } - - var fileMode = GetFileModeForFileAccess(fileAccess); + EnsureDirectory(fullPath); - try - { - return File.Open(fullPath, fileMode, fileAccess); - } - catch (IOException ex) when (ex is FileNotFoundException or DirectoryNotFoundException) - { - _logger.LogError(ex, "Unable to get file stream for {Path}: {Message}", normalizedPath, ex.Message); - return null; - } - } - - private FileMode GetFileModeForFileAccess(FileAccess fileAccess) - { - return fileAccess switch - { - FileAccess.Read => FileMode.Open, - FileAccess.Write => FileMode.Create, - FileAccess.ReadWrite => FileMode.OpenOrCreate, - _ => throw new ArgumentOutOfRangeException(nameof(fileAccess), fileAccess, null) - }; + var stream = streamMode == StreamMode.Read ? File.OpenRead(fullPath) : File.OpenWrite(fullPath); + return Task.FromResult(stream); } public Task GetFileInfoAsync(string path) @@ -140,39 +105,27 @@ public async Task SaveFileAsync(string path, Stream stream, CancellationTo if (stream == null) throw new ArgumentNullException(nameof(stream)); - string normalizedPath = path.NormalizePath(); - _logger.LogTrace("Saving {Path}", normalizedPath); - string file = Path.Combine(Folder, normalizedPath); - try { - using var fileStream = CreateFileStream(file); + using var fileStream = await GetFileStreamAsync(path, StreamMode.Write, cancellationToken); await stream.CopyToAsync(fileStream).AnyContext(); return true; } catch (Exception ex) { - _logger.LogError(ex, "Error saving {Path}: {Message}", normalizedPath, ex.Message); + _logger.LogError(ex, "Error saving {Path}: {Message}", path, ex.Message); return false; } } - private Stream CreateFileStream(string filePath) + private void EnsureDirectory(string normalizedPath) { - try - { - return File.Create(filePath); - } - catch (DirectoryNotFoundException) { } - - string directory = Path.GetDirectoryName(filePath); - if (directory != null) - { - _logger.LogInformation("Creating {Directory} directory", directory); - Directory.CreateDirectory(directory); - } + string directory = Path.GetDirectoryName(normalizedPath); + if (directory == null) + return; - return File.Create(filePath); + _logger.LogTrace("Ensuring director: {Directory}", directory); + Directory.CreateDirectory(directory); } public async Task RenameFileAsync(string path, string newPath, CancellationToken cancellationToken = default)