From 7fccb3810f9bc6880f1b16e00677ef78b7b6f9a5 Mon Sep 17 00:00:00 2001 From: Timerix Date: Thu, 26 Sep 2024 03:09:10 +0500 Subject: [PATCH] Filesystem --- DTLib/DTLib.csproj | 2 +- DTLib/Filesystem/Directory.cs | 41 ++++++++++-------------- DTLib/Filesystem/File.cs | 55 ++++++++++++++------------------ DTLib/Filesystem/IOPath.cs | 8 ++--- DTLib/Filesystem/Path.cs | 59 ++++++++++++++++++++--------------- DTLib/Filesystem/Symlink.cs | 15 --------- 6 files changed, 78 insertions(+), 102 deletions(-) delete mode 100644 DTLib/Filesystem/Symlink.cs diff --git a/DTLib/DTLib.csproj b/DTLib/DTLib.csproj index 267339f..24de329 100644 --- a/DTLib/DTLib.csproj +++ b/DTLib/DTLib.csproj @@ -2,7 +2,7 @@ DTLib - 1.4.1 + 1.4.2 Timerix Library for all my C# projects GIT diff --git a/DTLib/Filesystem/Directory.cs b/DTLib/Filesystem/Directory.cs index a1dd70d..7c7b1de 100644 --- a/DTLib/Filesystem/Directory.cs +++ b/DTLib/Filesystem/Directory.cs @@ -8,17 +8,18 @@ public static class Directory public static void Create(IOPath dir) { if (Exists(dir)) return; - + // creation of parent directories if (dir.Contains(Path.Sep)) { - var parentDir = dir.ParentDir(); - if(!Exists(parentDir)) + var parentDir = dir.ParentDir(); + if (!Exists(parentDir)) Create(parentDir); } - + System.IO.Directory.CreateDirectory(dir.Str); } + /// копирует все файлы и папки public static void Copy(IOPath sourceDir, IOPath newDir, bool owerwrite) { @@ -54,24 +55,24 @@ public static class Directory Delete(target_path); else throw new Exception($"directory {target_path} already exists"); } - else Directory.Create(target_path.ParentDir()); + else Create(target_path.ParentDir()); System.IO.Directory.Move(current_path.Str, target_path.Str); } - + /// удаляет папку со всеми подпапками и файлами - public static void Delete(IOPath dir) => + public static void Delete(IOPath dir) => System.IO.Directory.Delete(dir.Str, true); - public static IOPath[] GetFiles(IOPath dir) => + public static IOPath[] GetFiles(IOPath dir) => IOPath.ArrayCast(System.IO.Directory.GetFiles(dir.Str), true); - public static IOPath[] GetFiles(IOPath dir, string searchPattern) => + public static IOPath[] GetFiles(IOPath dir, string searchPattern) => IOPath.ArrayCast(System.IO.Directory.GetFiles(dir.Str, searchPattern), true); - public static IOPath[] GetDirectories(IOPath dir) => + public static IOPath[] GetDirectories(IOPath dir) => IOPath.ArrayCast(System.IO.Directory.GetDirectories(dir.Str), true); - public static IOPath[] GetDirectories(IOPath dir, string searchPattern) => + public static IOPath[] GetDirectories(IOPath dir, string searchPattern) => IOPath.ArrayCast(System.IO.Directory.GetDirectories(dir.Str, searchPattern), true); /// выдает список всех файлов @@ -86,9 +87,9 @@ public static class Directory all_subdirs = new List(); return GetAllFiles_internal(dir, all_subdirs); } + private static List GetAllFiles_internal(IOPath dir, List? all_subdirs) { - bool rememberSubdirs = all_subdirs is not null; var all_files = new List(); IOPath[] cur_files = GetFiles(dir); for (int i = 0; i < cur_files.Length; i++) @@ -96,20 +97,12 @@ public static class Directory IOPath[] cur_subdirs = GetDirectories(dir); for (int i = 0; i < cur_subdirs.Length; i++) { - if(rememberSubdirs) - all_subdirs?.Add(cur_subdirs[i]); + all_subdirs?.Add(cur_subdirs[i]); all_files.AddRange(GetAllFiles_internal(cur_subdirs[i], all_subdirs)); } + return all_files; } - public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory(); - - public static void CreateSymlink(string sourcePath, string symlinkPath) - { - if (symlinkPath.Contains(Path.Sep)) - Create(Path.ParentDir(symlinkPath)); - if (!Symlink.CreateSymbolicLink(symlinkPath, sourcePath, Symlink.SymlinkTarget.Directory)) - throw new InvalidOperationException($"some error occured while creating symlink\nDirectory.CreateSymlink({symlinkPath}, {sourcePath})"); - } -} + public static IOPath GetCurrent() => new IOPath(System.IO.Directory.GetCurrentDirectory(), true); +} \ No newline at end of file diff --git a/DTLib/Filesystem/File.cs b/DTLib/Filesystem/File.cs index e6bc4eb..0104d88 100644 --- a/DTLib/Filesystem/File.cs +++ b/DTLib/Filesystem/File.cs @@ -1,4 +1,7 @@ -namespace DTLib.Filesystem; +using FileMode = System.IO.FileMode; +using FileAccess = System.IO.FileAccess; + +namespace DTLib.Filesystem; public static class File { @@ -11,26 +14,25 @@ public static class File public static void Create(IOPath file) { if (Exists(file)) return; - + Directory.Create(file.ParentDir()); using System.IO.FileStream stream = System.IO.File.Create(file.Str); - stream.Close(); } public static void Copy(IOPath srcPath, IOPath newPath, bool overwrite) { if (Exists(newPath)) { - if(overwrite) System.IO.File.Delete(newPath.Str); + if (overwrite) + Delete(newPath); else throw new Exception($"file <{newPath}> alredy exists"); } else Directory.Create(newPath.ParentDir()); - using var srcFile=System.IO.File.Open(srcPath.Str, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite); - using var newFile=System.IO.File.Open(newPath.Str, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite); + + using var srcFile = OpenRead(srcPath); + using var newFile = OpenWrite(newPath); srcFile.CopyTo(newFile); - srcFile.Close(); newFile.Flush(); - newFile.Close(); } public static void Move(IOPath current_path, IOPath target_path, bool overwrite) @@ -42,6 +44,7 @@ public static class File else throw new Exception($"file {target_path} already exists"); } else Directory.Create(target_path.ParentDir()); + System.IO.File.Move(current_path.Str, target_path.Str); } @@ -49,13 +52,11 @@ public static class File public static byte[] ReadAllBytes(IOPath file) { - using System.IO.FileStream stream = OpenRead(file); int size = GetSize(file).ToInt(); byte[] output = new byte[size]; if (stream.Read(output, 0, size) < size) throw new Exception("can't read all bytes"); - stream.Close(); return output; } @@ -65,47 +66,37 @@ public static class File { using System.IO.FileStream stream = OpenWrite(file); stream.Write(content, 0, content.Length); - stream.Close(); } - public static void WriteAllText(IOPath file, string content) => WriteAllBytes(file, content.ToBytes(StringConverter.UTF8)); + public static void WriteAllText(IOPath file, string content) => + WriteAllBytes(file, content.ToBytes(StringConverter.UTF8)); public static void AppendAllBytes(IOPath file, byte[] content) { using System.IO.FileStream stream = OpenAppend(file); stream.Write(content, 0, content.Length); - stream.Close(); } - public static void AppendAllText(IOPath file, string content) => AppendAllBytes(file, content.ToBytes(StringConverter.UTF8)); + public static void AppendAllText(IOPath file, string content) => + AppendAllBytes(file, content.ToBytes(StringConverter.UTF8)); public static System.IO.FileStream OpenRead(IOPath file) { - if (!Exists(file)) + if (!Exists(file)) throw new Exception($"file not found: <{file}>"); - return System.IO.File.Open(file.Str, System.IO.FileMode.Open, System.IO.FileAccess.Read, + return System.IO.File.Open(file.Str, FileMode.Open, FileAccess.Read, System.IO.FileShare.ReadWrite | System.IO.FileShare.Delete); } public static System.IO.FileStream OpenWrite(IOPath file) { - if (Exists(file)) - Delete(file); - Create(file); - return System.IO.File.Open(file.Str, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.Read); - } - public static System.IO.FileStream OpenAppend(IOPath file) - { - - Create(file); - return System.IO.File.Open(file.Str, System.IO.FileMode.Append, System.IO.FileAccess.Write, System.IO.FileShare.Read); + Directory.Create(file.ParentDir()); + return System.IO.File.Open(file.Str, FileMode.OpenOrCreate, FileAccess.Write, System.IO.FileShare.Read); } - public static void CreateSymlink(IOPath sourcePath, IOPath symlinkPath) + public static System.IO.FileStream OpenAppend(IOPath file) { - if (symlinkPath.Contains(Path.Sep)) - Directory.Create(symlinkPath.ParentDir()); - if (!Symlink.CreateSymbolicLink(symlinkPath.Str, sourcePath.Str, Symlink.SymlinkTarget.File)) - throw new InvalidOperationException($"some error occured while creating symlink\nFile.CreateSymlink({symlinkPath}, {sourcePath})"); + Directory.Create(file.ParentDir()); + return System.IO.File.Open(file.Str, FileMode.Append, FileAccess.Write, System.IO.FileShare.Read); } -} +} \ No newline at end of file diff --git a/DTLib/Filesystem/IOPath.cs b/DTLib/Filesystem/IOPath.cs index 2769fd4..15ebf35 100644 --- a/DTLib/Filesystem/IOPath.cs +++ b/DTLib/Filesystem/IOPath.cs @@ -40,18 +40,18 @@ public readonly struct IOPath return new string(fixed_path); } - public static IOPath[] ArrayCast(string[] a, bool correct_separators=false) + public static IOPath[] ArrayCast(string[] a, bool separatorsFixed=false) { IOPath[] b = new IOPath[a.Length]; for (int i = 0; i < a.Length; i++) - b[i] = new IOPath(a[i], correct_separators); + b[i] = new IOPath(a[i], separatorsFixed); return b; } - public static IOPath[] ListCast(IList a, bool correct_separators=false) + public static IOPath[] ListCast(IList a, bool separatorsFixed=false) { IOPath[] b = new IOPath[a.Count]; for (int i = 0; i < a.Count; i++) - b[i] = new IOPath(a[i], correct_separators); + b[i] = new IOPath(a[i], separatorsFixed); return b; } diff --git a/DTLib/Filesystem/Path.cs b/DTLib/Filesystem/Path.cs index a483db3..e91004d 100644 --- a/DTLib/Filesystem/Path.cs +++ b/DTLib/Filesystem/Path.cs @@ -5,8 +5,8 @@ namespace DTLib.Filesystem; public static class Path { public static readonly char Sep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '\\' : '/'; - public static readonly char NotSep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '/' : '\\' ; - + public static readonly char NotSep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '/' : '\\'; + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ThrowIfEscapes(this IOPath path) @@ -14,7 +14,7 @@ public static class Path if (path.Str.Contains("..")) throw new Exception($"path <{path}> uses <..>, that's not allowed"); } - + /// Replaces characters restricted in filesystem path public static IOPath ReplaceRestrictedChars(string str) { @@ -25,16 +25,21 @@ public static class Path char c = r[i]; switch (c) { - case '\n': case '\r': - case ':': case ';': + case '\n': + case '\r': + case ':': + case ';': break; - case '/': case '\\': + case '/': + case '\\': b.Append('-'); break; - case '<': case '>': - case '?': case '|': + case '<': + case '>': + case '?': + case '|': b.Append('_'); - break; + break; case '"': b.Append('\''); break; @@ -46,22 +51,23 @@ public static class Path break; } } + return new IOPath(b.ToString(), true); } -#if !USE_SPAN - private static void CopyTo(this string s, char[] b, int startIndex) +#if !USE_SPAN + private static void CopyTo(this string s, char[] b, int startIndex) { for (int i = 0; i < s.Length; i++) - b[startIndex+i] = s[i]; + b[startIndex + i] = s[i]; } #endif - + public static IOPath Concat(params IOPath[] parts) { - var needSeparator = new bool[parts.Length-1]; + var needSeparator = new bool[parts.Length - 1]; int lengthSum = 0; - for (int i = 0; i < parts.Length-1; i++) + for (int i = 0; i < parts.Length - 1; i++) { lengthSum += parts[i].Length; if (!parts[i].Str.EndsWith(Sep) && !parts[i + 1].Str.StartsWith(Sep)) @@ -71,18 +77,19 @@ public static class Path } else needSeparator[i] = false; } - lengthSum += parts[parts.Length-1].Length; + + lengthSum += parts[parts.Length - 1].Length; var buffer = new char[lengthSum]; parts[0].Str.CopyTo(buffer, 0); int copiedChars = parts[0].Length; for (int i = 1; i < parts.Length; i++) { - if (needSeparator[i-1]) + if (needSeparator[i - 1]) buffer[copiedChars++] = Sep; parts[i].Str.CopyTo(buffer, copiedChars); copiedChars += parts[i].Length; } - + return new IOPath(new string(buffer), true); } @@ -91,15 +98,15 @@ public static class Path { int i = path.LastIndexOf(Sep); if (i == path.Length - 1) // ends with separator - i = path.LastIndexOf(Sep, i-1); + i = path.LastIndexOf(Sep, i - 1); if (i == -1) return path; - return path.Substring(i+1); + return path.Substring(i + 1); } - + public static IOPath Extension(this IOPath path) { int i = path.LastIndexOf('.'); - if (i == -1) + if (i == -1) return LastName(path); return path.Substring(i + 1); } @@ -107,7 +114,7 @@ public static class Path public static IOPath RemoveExtension(this IOPath path) { int i = path.LastIndexOf('.'); - if (i > 0) + if (i > 0) return path.Substring(0, i); return path; } @@ -116,10 +123,10 @@ public static class Path { int i = path.LastIndexOf(Sep); if (i == path.Length - 1) // ends with separator - i = path.LastIndexOf(Sep, i-1); + i = path.LastIndexOf(Sep, i - 1); if (i == -1) // no parent dir return $".{Sep}"; - return path.Remove(i+1); + return path.Remove(i + 1); } public static IOPath ReplaceBase(this IOPath path, IOPath baseDir, IOPath otherDir) @@ -133,6 +140,6 @@ public static class Path { if (!path.StartsWith(baseDir)) throw new Exception($"path <{path}> doesnt starts with <{baseDir}"); - return path.Substring(baseDir.Length+1); + return path.Substring(baseDir.Length + 1); } } \ No newline at end of file diff --git a/DTLib/Filesystem/Symlink.cs b/DTLib/Filesystem/Symlink.cs deleted file mode 100644 index 17aa56c..0000000 --- a/DTLib/Filesystem/Symlink.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Runtime.InteropServices; - -namespace DTLib.Filesystem; - -internal class Symlink -{ - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - internal static extern bool CreateSymbolicLink(string symlinkName, string sourceName, SymlinkTarget type); - - internal enum SymlinkTarget - { - File, - Directory - } -}