2021-07-09 14:48:12 -06:00
|
|
|
using System;
|
2022-03-29 13:44:21 +02:00
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2018-06-29 19:52:40 +02:00
|
|
|
using System.IO;
|
2021-07-09 14:48:12 -06:00
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using System.Text;
|
2018-06-29 19:52:40 +02:00
|
|
|
using System.Threading;
|
2022-01-06 13:35:24 +01:00
|
|
|
using Microsoft.Extensions.FileProviders;
|
2021-02-18 11:06:02 +01:00
|
|
|
using Umbraco.Cms.Core.IO;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
2021-02-18 11:06:02 +01:00
|
|
|
namespace Umbraco.Extensions
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
|
|
|
|
public static class FileSystemExtensions
|
|
|
|
|
{
|
2021-07-09 14:48:12 -06:00
|
|
|
public static string GetStreamHash(this Stream fileStream)
|
|
|
|
|
{
|
|
|
|
|
if (fileStream.CanSeek)
|
|
|
|
|
{
|
|
|
|
|
fileStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using HashAlgorithm alg = SHA1.Create();
|
|
|
|
|
|
|
|
|
|
// create a string output for the hash
|
|
|
|
|
var stringBuilder = new StringBuilder();
|
|
|
|
|
var hashedByteArray = alg.ComputeHash(fileStream);
|
|
|
|
|
foreach (var b in hashedByteArray)
|
|
|
|
|
{
|
|
|
|
|
stringBuilder.Append(b.ToString("x2"));
|
|
|
|
|
}
|
|
|
|
|
return stringBuilder.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-29 19:52:40 +02:00
|
|
|
/// <summary>
|
|
|
|
|
/// Attempts to open the file at <code>filePath</code> up to <code>maxRetries</code> times,
|
|
|
|
|
/// with a thread sleep time of <code>sleepPerRetryInMilliseconds</code> between retries.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static FileStream OpenReadWithRetry(this FileInfo file, int maxRetries = 5, int sleepPerRetryInMilliseconds = 50)
|
|
|
|
|
{
|
|
|
|
|
var retries = maxRetries;
|
|
|
|
|
|
|
|
|
|
while (retries > 0)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return File.OpenRead(file.FullName);
|
|
|
|
|
}
|
|
|
|
|
catch(IOException)
|
|
|
|
|
{
|
|
|
|
|
retries--;
|
|
|
|
|
|
|
|
|
|
if (retries == 0)
|
|
|
|
|
{
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread.Sleep(sleepPerRetryInMilliseconds);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
throw new ArgumentException("Retries must be greater than zero");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void CopyFile(this IFileSystem fs, string path, string newPath)
|
|
|
|
|
{
|
2022-04-29 08:19:34 +02:00
|
|
|
using (Stream stream = fs.OpenFile(path))
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
2022-04-29 08:19:34 +02:00
|
|
|
fs.AddFile(newPath, stream);
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetExtension(this IFileSystem fs, string path)
|
|
|
|
|
{
|
|
|
|
|
return Path.GetExtension(fs.GetFullPath(path));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string GetFileName(this IFileSystem fs, string path)
|
|
|
|
|
{
|
|
|
|
|
return Path.GetFileName(fs.GetFullPath(path));
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-27 01:17:32 -05:00
|
|
|
// TODO: Currently this is the only way to do this
|
2019-11-19 07:52:40 +01:00
|
|
|
public static void CreateFolder(this IFileSystem fs, string folderPath)
|
2018-06-29 19:52:40 +02:00
|
|
|
{
|
|
|
|
|
var path = fs.GetRelativePath(folderPath);
|
|
|
|
|
var tempFile = Path.Combine(path, Guid.NewGuid().ToString("N") + ".tmp");
|
|
|
|
|
using (var s = new MemoryStream())
|
|
|
|
|
{
|
|
|
|
|
fs.AddFile(tempFile, s);
|
|
|
|
|
}
|
|
|
|
|
fs.DeleteFile(tempFile);
|
|
|
|
|
}
|
2022-01-06 13:35:24 +01:00
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new <see cref="IFileProvider" /> from the file system.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fileSystem">The file system.</param>
|
|
|
|
|
/// <param name="fileProvider">When this method returns, contains an <see cref="IFileProvider"/> created from the file system.</param>
|
|
|
|
|
/// <returns>
|
|
|
|
|
/// <c>true</c> if the <see cref="IFileProvider" /> was successfully created; otherwise, <c>false</c>.
|
|
|
|
|
/// </returns>
|
2022-03-29 13:44:21 +02:00
|
|
|
public static bool TryCreateFileProvider(this IFileSystem fileSystem, [MaybeNullWhen(false)] out IFileProvider fileProvider)
|
2022-01-06 13:35:24 +01:00
|
|
|
{
|
|
|
|
|
fileProvider = fileSystem switch
|
|
|
|
|
{
|
|
|
|
|
IFileProviderFactory fileProviderFactory => fileProviderFactory.Create(),
|
|
|
|
|
_ => null
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return fileProvider != null;
|
|
|
|
|
}
|
2018-06-29 19:52:40 +02:00
|
|
|
}
|
|
|
|
|
}
|