Try your search with a different keyword or use * as a wildcard.
using System.Runtime.Versioning;
using System.Security.AccessControl;
using System.Text;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.FileProviders;
namespace Nop.Core.Infrastructure;
///
/// IO functions using the on-disk file system
///
public partial class NopFileProvider : PhysicalFileProvider, INopFileProvider
{
#region Ctor
///
/// Initializes a new instance of a NopFileProvider
///
/// Hosting environment
public NopFileProvider(IWebHostEnvironment webHostEnvironment)
: base(File.Exists(webHostEnvironment.ContentRootPath) ? Path.GetDirectoryName(webHostEnvironment.ContentRootPath)! : webHostEnvironment.ContentRootPath)
{
WebRootPath = File.Exists(webHostEnvironment.WebRootPath)
? Path.GetDirectoryName(webHostEnvironment.WebRootPath)
: webHostEnvironment.WebRootPath;
}
#endregion
#region Utilities
///
/// Depth-first recursive delete
///
///
protected virtual void DeleteDirectoryRecursive(string path)
{
Directory.Delete(path, true);
const int maxIterationToWait = 10;
var curIteration = 0;
//according to the documentation(https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365488.aspx)
//System.IO.Directory.Delete method ultimately (after removing the files) calls native
//RemoveDirectory function which marks the directory as "deleted". That's why we wait until
//the directory is actually deleted. For more details see https://stackoverflow.com/a/4245121
while (Directory.Exists(path))
{
curIteration += 1;
if (curIteration > maxIterationToWait)
return;
Thread.Sleep(100);
}
}
///
/// Determines if the string is a valid Universal Naming Convention (UNC)
/// for a server and share path.
///
/// The path to be tested.
/// if the path is a valid UNC path;
/// otherwise, .
protected static bool IsUncPath(string path)
{
return Uri.TryCreate(path, UriKind.Absolute, out var uri) && uri.IsUnc;
}
#endregion
#region Methods
///
/// Combines an array of strings into a path
///
/// An array of parts of the path
/// The combined paths
public virtual string Combine(params string[] paths)
{
var path = Path.Combine(paths.SelectMany(p => IsUncPath(p) ? [p] : p.Split('\\', '/')).ToArray());
if (Environment.OSVersion.Platform == PlatformID.Unix && !IsUncPath(path))
//add leading slash to correctly form path in the UNIX system
path = "/" + path;
return path;
}
///
/// Creates all directories and subdirectories in the specified path unless they already exist
///
/// The directory to create
public virtual void CreateDirectory(string path)
{
if (!DirectoryExists(path))
Directory.CreateDirectory(path);
}
///
/// Creates a file in the specified path
///
/// The path and name of the file to create
public virtual void CreateFile(string path)
{
if (FileExists(path))
return;
var fileInfo = new FileInfo(path);
CreateDirectory(fileInfo.DirectoryName);
//we use 'using' to close the file after it's created
using (File.Create(path))
{
}
}
///
/// Depth-first recursive delete, with handling for descendant directories open in Windows Explorer.
///
/// Directory path
public virtual void DeleteDirectory(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
//find more info about directory deletion
//and why we use this approach at https://stackoverflow.com/questions/329355/cannot-delete-directory-with-directory-deletepath-true
foreach (var directory in Directory.GetDirectories(path))
{
DeleteDirectory(directory);
}
try
{
DeleteDirectoryRecursive(path);
}
catch (IOException)
{
DeleteDirectoryRecursive(path);
}
catch (UnauthorizedAccessException)
{
DeleteDirectoryRecursive(path);
}
}
///
/// Deletes the specified file
///
/// The name of the file to be deleted. Wildcard characters are not supported
public virtual void DeleteFile(string filePath)
{
if (!FileExists(filePath))
return;
File.Delete(filePath);
}
///
/// Determines whether the given path refers to an existing directory on disk
///
/// The path to test
///
/// true if path refers to an existing directory; false if the directory does not exist or an error occurs when
/// trying to determine if the specified file exists
///
public virtual bool DirectoryExists(string path)
{
return Directory.Exists(path);
}
///
/// Moves a file or a directory and its contents to a new location
///
/// The path of the file or directory to move
///
/// The path to the new location for sourceDirName. If sourceDirName is a file, then destDirName
/// must also be a file name
///
public virtual void DirectoryMove(string sourceDirName, string destDirName)
{
Directory.Move(sourceDirName, destDirName);
}
///
/// Returns an enumerable collection of file names that match a search pattern in
/// a specified path, and optionally searches subdirectories.
///
/// The path to the directory to search
///
/// The search string to match against the names of files in path. This parameter
/// can contain a combination of valid literal path and wildcard (* and ?) characters
/// , but doesn't support regular expressions.
///
///
/// Specifies whether to search the current directory, or the current directory and all
/// subdirectories
///
///
/// An enumerable collection of the full names (including paths) for the files in
/// the directory specified by path and that match the specified search pattern
///
public virtual IEnumerable EnumerateFiles(string directoryPath, string searchPattern,
bool topDirectoryOnly = true)
{
return Directory.EnumerateFiles(directoryPath, searchPattern,
topDirectoryOnly ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);
}
///
/// Copies an existing file to a new file. Overwriting a file of the same name is allowed
///
/// The file to copy
/// The name of the destination file. This cannot be a directory
/// true if the destination file can be overwritten; otherwise, false
public virtual void FileCopy(string sourceFileName, string destFileName, bool overwrite = false)
{
File.Copy(sourceFileName, destFileName, overwrite);
}
///
/// Determines whether the specified file exists
///
/// The file to check
///
/// True if the caller has the required permissions and path contains the name of an existing file; otherwise,
/// false.
///
public virtual bool FileExists(string filePath)
{
return File.Exists(filePath);
}
///
/// Gets the length of the file in bytes, or -1 for a directory or non-existing files
///
/// File path
/// The length of the file
public virtual long FileLength(string path)
{
if (!FileExists(path))
return -1;
return new FileInfo(path).Length;
}
///
/// Moves a specified file to a new location, providing the option to specify a new file name
///
/// The name of the file to move. Can include a relative or absolute path
/// The new path and name for the file
public virtual void FileMove(string sourceFileName, string destFileName)
{
File.Move(sourceFileName, destFileName);
}
///
/// Returns the absolute path to the directory
///
/// An array of parts of the path
/// The absolute path to the directory
public virtual string GetAbsolutePath(params string[] paths)
{
var allPaths = new List();
if (paths.Any() && !paths[0].Contains(WebRootPath, StringComparison.InvariantCulture))
allPaths.Add(WebRootPath);
allPaths.AddRange(paths);
return Combine(allPaths.ToArray());
}
///
/// Gets a System.Security.AccessControl.DirectorySecurity object that encapsulates the access control list (ACL) entries for a specified directory
///
/// The path to a directory containing a System.Security.AccessControl.DirectorySecurity object that describes the file's access control list (ACL) information
/// An object that encapsulates the access control rules for the file described by the path parameter
[SupportedOSPlatform("windows")]
public virtual DirectorySecurity GetAccessControl(string path)
{
return new DirectoryInfo(path).GetAccessControl();
}
///
/// Returns the creation date and time of the specified file or directory
///
/// The file or directory for which to obtain creation date and time information
///
/// A System.DateTime structure set to the creation date and time for the specified file or directory. This value
/// is expressed in local time
///
public virtual DateTime GetCreationTime(string path)
{
return File.GetCreationTime(path);
}
///
/// Returns the names of the subdirectories (including their paths) that match the
/// specified search pattern in the specified directory
///
/// The path to the directory to search
///
/// The search string to match against the names of subdirectories in path. This
/// parameter can contain a combination of valid literal and wildcard characters
/// , but doesn't support regular expressions.
///
///
/// Specifies whether to search the current directory, or the current directory and all
/// subdirectories
///
///
/// An array of the full names (including paths) of the subdirectories that match
/// the specified criteria, or an empty array if no directories are found
///
public virtual string[] GetDirectories(string path, string searchPattern = "", bool topDirectoryOnly = true)
{
if (string.IsNullOrEmpty(searchPattern))
searchPattern = "*";
return Directory.GetDirectories(path, searchPattern,
topDirectoryOnly ? SearchOption.TopDirectoryOnly : SearchOption.AllDirectories);
}
///
/// Returns the directory information for the specified path string
///
/// The path of a file or directory
///
/// Directory information for path, or null if path denotes a root directory or is null. Returns
/// System.String.Empty if path does not contain directory information
///
public virtual string GetDirectoryName(string path)
{
return Path.GetDirectoryName(path);
}
///
/// Returns the directory name only for the specified path string
///
/// The path of directory
/// The directory name
public virtual string GetDirectoryNameOnly(string path)
{
return new DirectoryInfo(path).Name;
}
///
/// Returns the extension of the specified path string
///
/// The path string from which to get the extension
/// The extension of the specified path (including the period ".")
public virtual string GetFileExtension(string filePath)
{
return Path.GetExtension(filePath);
}
///
/// Returns the file name and extension of the specified path string
///
/// The path string from which to obtain the file name and extension
/// The characters after the last directory character in path
public virtual string GetFileName(string path)
{
return Path.GetFileName(path);
}
///
/// Returns the file name of the specified path string without the extension
///
/// The path of the file
/// The file name, minus the last period (.) and all characters following it
public virtual string GetFileNameWithoutExtension(string filePath)
{
return Path.GetFileNameWithoutExtension(filePath);
}
///
/// Returns the names of files (including their paths) that match the specified search
/// pattern in the specified directory, using a value to determine whether to search subdirectories.
///
/// The path to the directory to search
///
/// The search string to match against the names of files in path. This parameter
/// can contain a combination of valid literal path and wildcard (* and ?) characters
/// , but doesn't support regular expressions.
///
///
/// Specifies whether to search the current directory, or the current directory and all
/// subdirectories
///
///
/// An array of the full names (including paths) for the files in the specified directory
/// that match the specified search pattern, or an empty array if no files are found.
///
public virtual string[] GetFiles(string directoryPath, string searchPattern = "", bool topDirectoryOnly = true)
{
if (string.IsNullOrEmpty(searchPattern))
searchPattern = "*.*";
return Directory.GetFileSystemEntries(directoryPath, searchPattern,
new EnumerationOptions
{
IgnoreInaccessible = true,
MatchCasing = MatchCasing.CaseInsensitive,
RecurseSubdirectories = !topDirectoryOnly,
});
}
///
/// Returns the date and time the specified file or directory was last accessed
///
/// The file or directory for which to obtain access date and time information
/// A System.DateTime structure set to the date and time that the specified file
public virtual DateTime GetLastAccessTime(string path)
{
return File.GetLastAccessTime(path);
}
///
/// Returns the date and time the specified file or directory was last written to
///
/// The file or directory for which to obtain write date and time information
///
/// A System.DateTime structure set to the date and time that the specified file or directory was last written to.
/// This value is expressed in local time
///
public virtual DateTime GetLastWriteTime(string path)
{
return File.GetLastWriteTime(path);
}
///
/// Returns the date and time, in coordinated universal time (UTC), that the specified file or directory was last
/// written to
///
/// The file or directory for which to obtain write date and time information
///
/// A System.DateTime structure set to the date and time that the specified file or directory was last written to.
/// This value is expressed in UTC time
///
public virtual DateTime GetLastWriteTimeUtc(string path)
{
return File.GetLastWriteTimeUtc(path);
}
///
/// Creates or opens a file at the specified path for read/write access
///
/// The path and name of the file to create
/// A that provides read/write access to the file specified in
public FileStream GetOrCreateFile(string path)
{
if (FileExists(path))
return File.Open(path, FileMode.Open, FileAccess.ReadWrite);
var fileInfo = new FileInfo(path);
CreateDirectory(fileInfo.DirectoryName);
return File.Create(path);
}
///
/// Retrieves the parent directory of the specified path
///
/// The path for which to retrieve the parent directory
/// The parent directory, or null if path is the root directory, including the root of a UNC server or share name
public virtual string GetParentDirectory(string directoryPath)
{
return Directory.GetParent(directoryPath).FullName;
}
///
/// Gets a virtual path from a physical disk path.
///
/// The physical disk path
/// The virtual path. E.g. "~/bin"
public virtual string GetVirtualPath(string path)
{
if (string.IsNullOrEmpty(path))
return path;
if (!IsDirectory(path) && FileExists(path))
path = new FileInfo(path).DirectoryName;
path = path?.Replace(WebRootPath, string.Empty).Replace('\\', '/').Trim('/').TrimStart('~', '/');
return $"~/{path ?? string.Empty}";
}
///
/// Checks if the path is directory
///
/// Path for check
/// True, if the path is a directory, otherwise false
public virtual bool IsDirectory(string path)
{
return DirectoryExists(path);
}
///
/// Maps a virtual path to a physical disk path.
///
/// The path to map. E.g. "~/bin"
/// The physical path. E.g. "c:\inetpub\wwwroot\bin"
public virtual string MapPath(string path)
{
path = path.Replace("~/", string.Empty).TrimStart('/');
//if virtual path has slash on the end, it should be after transform the virtual path to physical path too
var pathEnd = path.EndsWith('/') ? Path.DirectorySeparatorChar.ToString() : string.Empty;
return Combine(Root ?? string.Empty, path) + pathEnd;
}
///
/// Reads the contents of the file into a byte array
///
/// The file for reading
///
/// A task that represents the asynchronous operation
/// The task result contains a byte array containing the contents of the file
///
public virtual async Task ReadAllBytesAsync(string filePath)
{
return File.Exists(filePath) ? await File.ReadAllBytesAsync(filePath) : Array.Empty();
}
///
/// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
///
/// The file to open for reading
/// The encoding applied to the contents of the file
///
/// A task that represents the asynchronous operation
/// The task result contains a string containing all lines of the file
///
public virtual async Task ReadAllTextAsync(string path, Encoding encoding)
{
await using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var streamReader = new StreamReader(fileStream, encoding);
return await streamReader.ReadToEndAsync();
}
///
/// Opens a file, reads all lines of the file with the specified encoding, and then closes the file.
///
/// The file to open for reading
/// The encoding applied to the contents of the file
/// A string containing all lines of the file
public virtual string ReadAllText(string path, Encoding encoding)
{
using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var streamReader = new StreamReader(fileStream, encoding);
return streamReader.ReadToEnd();
}
///
/// Writes the specified byte array to the file
///
/// The file to write to
/// The bytes to write to the file
/// A task that represents the asynchronous operation
public virtual async Task WriteAllBytesAsync(string filePath, byte[] bytes)
{
await File.WriteAllBytesAsync(filePath, bytes);
}
///
/// Creates a new file, writes the specified string to the file using the specified encoding,
/// and then closes the file. If the target file already exists, it is overwritten.
///
/// The file to write to
/// The string to write to the file
/// The encoding to apply to the string
/// A task that represents the asynchronous operation
public virtual async Task WriteAllTextAsync(string path, string contents, Encoding encoding)
{
await File.WriteAllTextAsync(path, contents, encoding);
}
///
/// Creates a new file, writes the specified string to the file using the specified encoding,
/// and then closes the file. If the target file already exists, it is overwritten.
///
/// The file to write to
/// The string to write to the file
/// The encoding to apply to the string
public virtual void WriteAllText(string path, string contents, Encoding encoding)
{
File.WriteAllText(path, contents, encoding);
}
/// Locate a file at the given path.
/// Relative path that identifies the file.
/// The file information. Caller must check Exists property.
public new virtual IFileInfo GetFileInfo(string subpath)
{
subpath = subpath.Replace(Root, string.Empty);
return base.GetFileInfo(subpath);
}
#endregion
#region Properties
///
/// Gets or sets the absolute path to the directory that contains the web-servable application content files.
///
public string WebRootPath { get; }
#endregion
}