diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj
index 03fcbbd374..88fc08e34e 100644
--- a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj
+++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo.Abp.BlobStoring.FileSystem.csproj
@@ -16,6 +16,7 @@
+
diff --git a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs
index aafba5b696..cbfe4bcaf7 100644
--- a/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs
+++ b/framework/src/Volo.Abp.BlobStoring.FileSystem/Volo/Abp/BlobStoring/FileSystem/FileSystemBlobProvider.cs
@@ -1,5 +1,7 @@
-using System.IO;
+using System;
+using System.IO;
using System.Threading.Tasks;
+using Polly;
using Volo.Abp.DependencyInjection;
using Volo.Abp.IO;
@@ -8,12 +10,12 @@ namespace Volo.Abp.BlobStoring.FileSystem
public class FileSystemBlobProvider : BlobProviderBase, ITransientDependency
{
protected IBlobFilePathCalculator FilePathCalculator { get; }
-
+
public FileSystemBlobProvider(IBlobFilePathCalculator filePathCalculator)
{
FilePathCalculator = filePathCalculator;
}
-
+
public override async Task SaveAsync(BlobProviderSaveArgs args)
{
var filePath = FilePathCalculator.Calculate(args);
@@ -22,22 +24,27 @@ namespace Volo.Abp.BlobStoring.FileSystem
{
throw new BlobAlreadyExistsException($"Saving BLOB '{args.BlobName}' does already exists in the container '{args.ContainerName}'! Set {nameof(args.OverrideExisting)} if it should be overwritten.");
}
-
+
DirectoryHelper.CreateIfNotExists(Path.GetDirectoryName(filePath));
var fileMode = args.OverrideExisting
? FileMode.Create
: FileMode.CreateNew;
-
- using (var fileStream = File.Open(filePath, fileMode, FileAccess.Write))
- {
- await args.BlobStream.CopyToAsync(
- fileStream,
- args.CancellationToken
- );
- await fileStream.FlushAsync();
- }
+ await Policy.Handle()
+ .WaitAndRetryAsync(2, retryCount => TimeSpan.FromSeconds(retryCount))
+ .ExecuteAsync(async () =>
+ {
+ using (var fileStream = File.Open(filePath, fileMode, FileAccess.Write))
+ {
+ await args.BlobStream.CopyToAsync(
+ fileStream,
+ args.CancellationToken
+ );
+
+ await fileStream.FlushAsync();
+ }
+ });
}
public override Task DeleteAsync(BlobProviderDeleteArgs args)
@@ -52,21 +59,31 @@ namespace Volo.Abp.BlobStoring.FileSystem
return ExistsAsync(filePath);
}
- public override Task GetOrNullAsync(BlobProviderGetArgs args)
+ public override async Task GetOrNullAsync(BlobProviderGetArgs args)
{
var filePath = FilePathCalculator.Calculate(args);
if (!File.Exists(filePath))
{
- return Task.FromResult(null);
+ return null;
}
- return Task.FromResult(File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read));
+ return await Policy.Handle()
+ .WaitAndRetryAsync(2, retryCount => TimeSpan.FromSeconds(retryCount))
+ .ExecuteAsync(async () =>
+ {
+ using (var fileStream = File.OpenRead(filePath))
+ {
+ var memoryStream = new MemoryStream();
+ await fileStream.CopyToAsync(memoryStream, args.CancellationToken);
+ return memoryStream;
+ }
+ });
}
-
+
protected virtual Task ExistsAsync(string filePath)
{
return Task.FromResult(File.Exists(filePath));
}
}
-}
\ No newline at end of file
+}
diff --git a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
index 466d73b2a7..bd85773a9b 100644
--- a/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
+++ b/framework/src/Volo.Abp.Core/System/IO/AbpStreamExtensions.cs
@@ -9,6 +9,7 @@ namespace System.IO
{
using (var memoryStream = new MemoryStream())
{
+ stream.Position = 0;
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
@@ -18,6 +19,7 @@ namespace System.IO
{
using (var memoryStream = new MemoryStream())
{
+ stream.Position = 0;
await stream.CopyToAsync(memoryStream, cancellationToken);
return memoryStream.ToArray();
}
@@ -25,6 +27,7 @@ namespace System.IO
public static Task CopyToAsync(this Stream stream, Stream destination, CancellationToken cancellationToken)
{
+ stream.Position = 0;
return stream.CopyToAsync(
destination,
81920, //this is already the default value, but needed to set to be able to pass the cancellationToken