using System.Diagnostics.CodeAnalysis; using System.Text; using System.Text.Json.Serialization; using StabilityMatrix.Core.Converters.Json; namespace StabilityMatrix.Core.Models.FileInterfaces; [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] [JsonConverter(typeof(StringJsonConverter))] public class FilePath : FileSystemPath, IPathObject { private FileInfo? _info; // ReSharper disable once MemberCanBePrivate.Global [JsonIgnore] public FileInfo Info => _info ??= new FileInfo(FullPath); [JsonIgnore] public bool IsSymbolicLink { get { Info.Refresh(); return Info.Attributes.HasFlag(FileAttributes.ReparsePoint); } } [JsonIgnore] public bool Exists => Info.Exists; [JsonIgnore] public string Name => Info.Name; [JsonIgnore] public string NameWithoutExtension => Path.GetFileNameWithoutExtension(Info.Name); /// /// Get the directory of the file. /// [JsonIgnore] public DirectoryPath? Directory { get { try { return Info.Directory == null ? null : new DirectoryPath(Info.Directory); } catch (DirectoryNotFoundException) { return null; } } } public FilePath(string path) : base(path) { } public FilePath(FileInfo fileInfo) : base(fileInfo.FullName) { _info = fileInfo; } public FilePath(FileSystemPath path) : base(path) { } public FilePath(params string[] paths) : base(paths) { } public long GetSize() { Info.Refresh(); return Info.Length; } public long GetSize(bool includeSymbolicLinks) { if (!includeSymbolicLinks && IsSymbolicLink) return 0; return GetSize(); } public Task GetSizeAsync(bool includeSymbolicLinks) { return Task.Run(() => GetSize(includeSymbolicLinks)); } /// Creates an empty file. public void Create() => File.Create(FullPath).Close(); /// Deletes the file public void Delete() => File.Delete(FullPath); // Methods specific to files /// Read text public string ReadAllText() => File.ReadAllText(FullPath); /// Read text asynchronously public Task ReadAllTextAsync(CancellationToken ct = default) { return File.ReadAllTextAsync(FullPath, ct); } /// Write text public void WriteAllText(string text) => File.WriteAllText(FullPath, text, Encoding.UTF8); /// Write text asynchronously public Task WriteAllTextAsync(string text, CancellationToken ct = default) { return File.WriteAllTextAsync(FullPath, text, Encoding.UTF8, ct); } /// Read bytes public byte[] ReadAllBytes() => File.ReadAllBytes(FullPath); /// Read bytes asynchronously public Task ReadAllBytesAsync(CancellationToken ct = default) { return File.ReadAllBytesAsync(FullPath, ct); } /// Write bytes public void WriteAllBytes(byte[] bytes) => File.WriteAllBytes(FullPath, bytes); /// Write bytes asynchronously public Task WriteAllBytesAsync(byte[] bytes, CancellationToken ct = default) { return File.WriteAllBytesAsync(FullPath, bytes, ct); } /// /// Move the file to a directory. /// public FilePath MoveTo(FilePath destinationFile) { Info.MoveTo(destinationFile.FullPath, true); // Return the new path return destinationFile; } /// /// Move the file to a directory. /// public async Task MoveToAsync(DirectoryPath directory) { await Task.Run(() => Info.MoveTo(directory.FullPath)).ConfigureAwait(false); // Return the new path return directory.JoinFile(this); } /// /// Move the file to a target path. /// public async Task MoveToAsync(FilePath destinationFile) { await Task.Run(() => Info.MoveTo(destinationFile.FullPath)).ConfigureAwait(false); // Return the new path return destinationFile; } /// /// Copy the file to a target path. /// public FilePath CopyTo(FilePath destinationFile, bool overwrite = false) { Info.CopyTo(destinationFile.FullPath, overwrite); // Return the new path return destinationFile; } // Implicit conversions to and from string public static implicit operator string(FilePath path) => path.FullPath; public static implicit operator FilePath(string path) => new(path); }