レコードクラスでファイルパス管理クラスFielSystemPathのサンプルコードを書きました。

更に機能を追加しようと思い、ファイルの有無などファイルシステムに依存するコードを別クラスFileSystemPathExにまとめました。
また、FielSystemPathとは関係なく、新規にオブジェクトを作成するstaticメッソドをクラスFileSystemPathUtils.csにまとめました。

C#レコードクラスで作るファイルパス管理のサンプルコード
C#のレコードクラスを試してみました。サンプルコードファイル名:FileSystemPath.cspublic record class FileSystemPath{ public string Path { get; } private...
更に機能を追加しようと思い、ファイルの有無などファイルシステムに依存するコードを別クラスFileSystemPathExにまとめました。
また、FielSystemPathとは関係なく、新規にオブジェクトを作成するstaticメッソドをクラスFileSystemPathUtils.csにまとめました。
サンプルコード
ファイル名:FielSystemPath.cs
public record class FileSystemPath : IFileSystemPath
{
public string Path { get; }
static readonly char[] InvalidChars = ['"', '<', '>', '|', '\0'];
static void Validation(string path)
{
if (string.IsNullOrWhiteSpace(path))
{
throw new ArgumentException("パスが空白または null です。", nameof(path));
}
// 無効な文字チェック
if (path.IndexOfAny(InvalidChars) >= 0)
{
throw new ArgumentException($"パスに無効な文字が含まれています。{path}", nameof(path));
}
}
private static string ValidateAndJoin(params string[] paths)
{
foreach (var path in paths)
{
Validation(path);
}
return System.IO.Path.Join(paths);
}
public FileSystemPath(string path)
{
Validation(path);
Path = path;
}
public FileSystemPath(params string[] paths)
{
Path = ValidateAndJoin(paths);
}
public FileSystemPath(List<string> pathList)
{
Path = ValidateAndJoin([.. pathList]);
}
// 文字列化
public override string ToString() => Path;
// 親ディレクトリを取得
public IFileSystemPath GetDirectory()
{
string? dir = System.IO.Path.GetDirectoryName(this.Path);
if (string.IsNullOrEmpty(dir))
{
throw new InvalidOperationException("親ディレクトリが取得できません。");
}
return new FileSystemPath(dir);
}
// ルートディレクトリか?
public bool IsRoot()
{
return string.Equals(
System.IO.Path.GetFullPath(this.Path),
System.IO.Path.GetPathRoot(this.Path),
StringComparison.OrdinalIgnoreCase
);
}
// 拡張子を取得
public string GetExtension() => System.IO.Path.GetExtension(this.Path);
// ファイル名を取得
public string GetFileName() => System.IO.Path.GetFileName(this.Path);
// 拡張子抜きファイル名を取得
public string GetBaseName() => System.IO.Path.GetFileNameWithoutExtension(this.Path);
// ルートディレクトリを取得
public IFileSystemPath GetRoot()
{
string rootStr = System.IO.Path.GetPathRoot(this.Path) ?? "";
return new FileSystemPath(rootStr);
}
/*
// 絶対パスを取得 (文字列操作ではなく、実行環境依存)
public string GetFullPath() => System.IO.Path.GetFullPath(this.Path);
*/
// 拡張子があるか?
public bool HasExtension() => System.IO.Path.HasExtension(this.Path);
// ルートが含まれているか?
public bool IsPathRooted() => System.IO.Path.IsPathRooted(this.Path);
// 連結
public IFileSystemPath Combine(IFileSystemPath path)
{
string result = System.IO.Path.Combine(this.Path, path.Path);
return new FileSystemPath(result);
}
// 拡張子を追加
public IFileSystemPath AppendExtension(string ext)
{
if (string.IsNullOrWhiteSpace(ext))
{
throw new ArgumentException("拡張子が空です", nameof(ext));
}
// 拡張子先頭にドットがなければ追加
if (!ext.StartsWith("."))
{
ext = "." + ext;
}
string newPath = (this.ToString() + ext);
return new FileSystemPath(newPath);
}
// 拡張子の置換
public IFileSystemPath ChangeExtension(string newExt)
{
if (string.IsNullOrWhiteSpace(newExt))
{
throw new ArgumentException("拡張子が空です", nameof(newExt));
}
// 拡張子先頭にドットがなければ追加
if (!newExt.StartsWith("."))
{
newExt = "." + newExt;
}
string newPath = System.IO.Path.ChangeExtension(this.ToString(), newExt);
return new FileSystemPath(newPath);
}
// 相対パスを取得
public IFileSystemPath GetRelativePath(IFileSystemPath basePath)
{
ArgumentNullException.ThrowIfNull(basePath);
string relativePath = System.IO.Path.GetRelativePath(basePath.Path, this.Path);
return new FileSystemPath(relativePath);
}
// 末尾が区切り文字か?
public bool EndsInDirectorySeparator() => System.IO.Path.EndsInDirectorySeparator(this.Path);
// ランダムなフォルダー名またはファイル名を返します。
public IFileSystemPath GetRandomFileName()
{
string path = System.IO.Path.GetRandomFileName();
return new FileSystemPath(path);
}
// ファイル パスが完全修飾されているか
public bool IsPathFullyQualified() => System.IO.Path.IsPathFullyQualified(this.Path);
// 末尾の区切り文字を削除
public IFileSystemPath TrimEndingDirectorySeparator()
{
string path = System.IO.Path.TrimEndingDirectorySeparator(this.Path);
return new FileSystemPath(path);
}
}
ファイル名:FileSystemPathEx.cs
public record class FileSystemPathEx : IFileSystemPathEx
{
IFileSystemPath _FileSystemPath;
public IFileSystemPath InnerPath { get => _FileSystemPath; }
// コンストラクタ
public FileSystemPathEx(string path)
{
_FileSystemPath = new FileSystemPath(path);
}
// コンストラクタ
public FileSystemPathEx(IFileSystemPath fileSystemPath)
{
_FileSystemPath = fileSystemPath;
}
// 絶対パスを取得
public IFileSystemPath GetFullPath()
{
string fullPath = System.IO.Path.GetFullPath(_FileSystemPath.Path);
return new FileSystemPath(fullPath);
}
// ファイルの存在確認
public bool IsFile() => System.IO.File.Exists(_FileSystemPath.Path);
// ディレクトリの存在確認
public bool IsDirectory() => System.IO.Directory.Exists(_FileSystemPath.Path);
// ファイルまたはディレクトリが存在確認
//public bool Exists() => System.IO.Path.Exists(_FileSystemPath.Path);
public bool Exists() =>
System.IO.File.Exists(_FileSystemPath.Path) || System.IO.Directory.Exists(_FileSystemPath.Path);
}
ファイル名:FileSystemPathUtils.cs
public class FileSystemPathUtils
{
// 拡張子.tmpの一時ファイルをディスク上に作成し、そのファイルの完全パスを返します。
public static IFileSystemPath GetTempFileName()
{
string fullPath = System.IO.Path.GetTempFileName();
return new FileSystemPath(fullPath);
}
// 現在のユーザーの一時フォルダーのパスを返します。
public static IFileSystemPath GetTempPath()
{
string fullPath = System.IO.Path.GetTempPath();
return new FileSystemPath(fullPath);
}
}
ファイル名:IFielSystemPath.cs
public interface IFileSystemPath
{
// パス
public string Path { get; }
// 親ディレクトリを取得
public IFileSystemPath GetDirectory();
// ルートディレクトリか?
public bool IsRoot();
// 拡張子を取得
public string GetExtension();
// ファイル名を取得
public string GetFileName();
// 拡張子抜きファイル名を取得
public string GetBaseName();
// ルートディレクトリを取得
public IFileSystemPath GetRoot();
/*
// 絶対パスを取得 (文字列操作ではなく、実行環境依存)
public string GetFullPath() => System.IO.Path.GetFullPath(this.Path);
*/
// 拡張子があるか?
public bool HasExtension();
// ルートが含まれているか?
public bool IsPathRooted();
// 連結
public IFileSystemPath Combine(IFileSystemPath path);
// 拡張子を追加
public IFileSystemPath AppendExtension(string ext);
// 拡張子の置換
public IFileSystemPath ChangeExtension(string newExt);
// 相対パスを取得
public IFileSystemPath GetRelativePath(IFileSystemPath basePath);
// 末尾が区切り文字か?
public bool EndsInDirectorySeparator();
// ランダムなフォルダー名またはファイル名を返します。
public IFileSystemPath GetRandomFileName();
// ファイル パスが完全修飾されているか
public bool IsPathFullyQualified();
// 末尾の区切り文字を削除
public IFileSystemPath TrimEndingDirectorySeparator();
}
ファイル名:IFileSystemPathEx.cs
public interface IFileSystemPathEx
{
public IFileSystemPath InnerPath { get; }
// 絶対パスを取得
public IFileSystemPath GetFullPath();
// ファイルまたはディレクトリが存在確認
public bool Exists();
// ファイルの存在確認
public bool IsFile();
// ディレクトリの存在確認
public bool IsDirectory();
}
コメント