Filesystem.New

This commit is contained in:
Timerix22 2022-11-11 19:43:38 +06:00
parent f6d045ae2d
commit be9f61329e
5 changed files with 254 additions and 15 deletions

View File

@ -44,30 +44,47 @@ public static class StringConverter
public static bool StartsWith(this string s, char c) => s[0] == c;
public static bool EndsWith(this string s, char c) => s[s.Length - 1] == c;
public static string MergeToString(params object[] parts)
public static string MergeToString<TVal>(params TVal[] parts)
{
if (parts.Length == 0)
return "";
StringBuilder builder = new();
for (int i = 0; i < parts.Length; i++)
builder.Append(parts[i]);
return builder.ToString();
}
public static string MergeToString<T>(this IEnumerable<T> collection, string separator)
public static string MergeToString<TVal, TSep>(TSep separator, params TVal[] parts)
{
StringBuilder builder = new();
foreach (T elem in collection)
{
builder.Append(elem);
builder.Append(separator);
}
if (builder.Length == 0)
if (parts.Length == 0)
return "";
builder.Remove(builder.Length - separator.Length, separator.Length);
StringBuilder builder = new();
builder.Append(parts[0]);
for (int i = 1; i < parts.Length; i++)
{
builder.Append(separator);
builder.Append(parts[i]);
}
return builder.ToString();
}
public static string MergeToString<T>(this IEnumerable<T> collection)
public static string MergeToString<TVal, TSep>(this IEnumerable<TVal> collection, TSep separator)
{
StringBuilder builder = new();
foreach (T elem in collection)
using var e = collection.GetEnumerator();
if(e.MoveNext())
builder.Append(e.Current);
while (e.MoveNext())
{
builder.Append(separator);
builder.Append(e.Current);
}
return builder.ToString();
}
public static string MergeToString<TVal>(this IEnumerable<TVal> collection)
{
StringBuilder builder = new();
foreach (var elem in collection)
builder.Append(elem);
return builder.ToString();
}

View File

@ -3,7 +3,7 @@ namespace DTLib.Filesystem;
public static class File
{
public static int GetSize(string file) => new System.IO.FileInfo(file).Length.ToInt();
public static long GetSize(string file) => new System.IO.FileInfo(file).Length;
public static bool Exists(string file) => System.IO.File.Exists(file);
@ -32,9 +32,10 @@ public static class File
public static byte[] ReadAllBytes(string file)
{
using System.IO.FileStream stream = OpenRead(file);
int size = GetSize(file);
int size = GetSize(file).ToInt();
byte[] output = new byte[size];
stream.Read(output, 0, size);
if (stream.Read(output, 0, size) < size)
throw new Exception("can't read all bytes");
stream.Close();
return output;
}

View File

@ -0,0 +1,120 @@
namespace DTLib.Filesystem.New;
public static class Directory
{
public static bool Exists(string dir) => System.IO.Directory.Exists(dir);
// создает папку, если её не существует
public static void Create(string dir)
{
if (!Exists(dir))
{
// проверяет существование папки, в которой нужно создать dir
if (dir.Contains(Путь.Разд) && !Exists(dir.Remove(dir.LastIndexOf(Путь.Разд))))
Create(dir.Remove(dir.LastIndexOf(Путь.Разд)));
System.IO.Directory.CreateDirectory(dir);
}
}
// копирует все файлы и папки
public static void Copy(string source_dir, string new_dir, bool owerwrite = false)
{
Create(new_dir);
var subdirs = new List<string>();
List<string> files = GetAllFiles(source_dir, ref subdirs);
for (int i = 0; i < subdirs.Count; i++)
Create(subdirs[i].Replace(source_dir, new_dir));
for (int i = 0; i < files.Count; i++)
File.Copy(files[i], files[i].Replace(source_dir, new_dir), owerwrite);
}
// копирует все файлы и папки и выдаёт список конфликтующих файлов
public static void Copy(string source_dir, string new_dir, out List<string> conflicts, bool owerwrite = false)
{
conflicts = new List<string>();
var subdirs = new List<string>();
List<string> files = GetAllFiles(source_dir, ref subdirs);
Create(new_dir);
for (int i = 0; i < subdirs.Count; i++)
Create(subdirs[i].Replace(source_dir, new_dir));
for (int i = 0; i < files.Count; i++)
{
string newfile = files[i].Replace(source_dir, new_dir);
if (File.Exists(newfile))
conflicts.Add(newfile);
File.Copy(files[i], newfile, owerwrite);
}
}
// удаляет папку со всеми подпапками и файлами
public static void Delete(string dir)
{
var subdirs = new List<string>();
List<string> files = GetAllFiles(dir, ref subdirs);
for (int i = 0; i < files.Count; i++)
File.Delete(files[i]);
for (int i = subdirs.Count - 1; i >= 0; i--)
{
Log($"deleting {subdirs[i]}");
if (Exists(subdirs[i]))
System.IO.Directory.Delete(subdirs[i], true);
}
Log($"deleting {dir}");
if (Exists(dir))
System.IO.Directory.Delete(dir, true);
}
public static string[] GetFiles(string dir) => System.IO.Directory.GetFiles(dir);
public static string[] GetFiles(string dir, string searchPattern) => System.IO.Directory.GetFiles(dir, searchPattern);
public static string[] GetDirectories(string dir) => System.IO.Directory.GetDirectories(dir);
// выдает список всех файлов
public static List<string> GetAllFiles(string dir)
{
var all_files = new List<string>();
string[] cur_files = GetFiles(dir);
for (int i = 0; i < cur_files.Length; i++)
all_files.Add(cur_files[i]);
string[] cur_subdirs = GetDirectories(dir);
for (int i = 0; i < cur_subdirs.Length; i++)
all_files.AddRange(GetAllFiles(cur_subdirs[i]));
return all_files;
}
// выдает список всех файлов и подпапок в папке
public static List<string> GetAllFiles(string dir, ref List<string> all_subdirs)
{
var all_files = new List<string>();
string[] cur_files = GetFiles(dir);
for (int i = 0; i < cur_files.Length; i++)
all_files.Add(cur_files[i]);
string[] cur_subdirs = GetDirectories(dir);
for (int i = 0; i < cur_subdirs.Length; i++)
{
all_subdirs.Add(cur_subdirs[i]);
all_files.AddRange(GetAllFiles(cur_subdirs[i], ref all_subdirs));
}
return all_files;
}
public static string GetCurrent() => System.IO.Directory.GetCurrentDirectory();
public static void CreateSymlink(string sourceName, string symlinkName)
{
if (symlinkName.Contains(Путь.Разд))
Create(symlinkName.Remove(symlinkName.LastIndexOf(Путь.Разд)));
if (!Symlink.CreateSymbolicLink(symlinkName, sourceName, Symlink.SymlinkTarget.Directory))
throw new InvalidOperationException($"some error occured while creating symlink\nDirectory.CreateSymlink({symlinkName}, {sourceName})");
}
// copies directory with symlinks instead of files
public static int SymCopy(string srcdir, string newdir)
{
List<string> files = GetAllFiles(srcdir);
if (!srcdir.EndsWith(Путь.Разд)) srcdir += Путь.Разд;
if (!newdir.EndsWith(Путь.Разд)) newdir += Путь.Разд;
int i = 0;
for (; i < files.Count; i++)
File.CreateSymlink(files[i], files[i].Replace(srcdir, newdir));
return i;
}
}

View File

@ -0,0 +1,62 @@
using System.IO;
namespace DTLib.Filesystem.New;
public class File
{
public enum FileOpenMode
{
// open a file for reading
Read=1,
// (re)create a file for writing
Write=2,
// opens file for writing additional data to the end / creates new file
Append=4,
// (re)creates file for reading/writing
ReadWrite=Read|Write,
// opens file for readng/writing additional data to the end / creates new file
ReadAppend=Read|Append
}
public readonly FileOpenMode Mode;
public readonly FileStream Stream;
public string Name;
public File(string path, FileOpenMode mode)
{
if(!Exists(path))
{
if (mode == FileOpenMode.Read)
throw new Exception($"file <{path}> is not found");
}
Mode = mode;
Stream = mode switch
{
FileOpenMode.Read => System.IO.File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite),
FileOpenMode.Write => System.IO.File.Open(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite),
FileOpenMode.Append => System.IO.File.Open(path, FileMode.Append, FileAccess.Write, FileShare.ReadWrite),
FileOpenMode.ReadWrite => System.IO.File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite),
FileOpenMode.ReadAppend => System.IO.File.Open(path, FileMode.Append, FileAccess.ReadWrite, FileShare.ReadWrite),
_ => throw new Exception($"unknown file mode: {mode}")
};
}
public static bool Exists(string path) => System.IO.File.Exists(path);
public static void Create(string path)
{
if (Exists(path))
throw new Exception($"file <{path} already exists");
int sepIndex = path.LastIndexOf(Path.Sep);
if (sepIndex>-1)
Directory.Create(path.Remove(sepIndex));
System.IO.File.Create(path).Close();
}
public static void Delete(string path) => System.IO.File.Delete(path);
public void Delete(string path)
{
}
}

View File

@ -0,0 +1,39 @@
using System.Runtime.CompilerServices;
namespace DTLib.Filesystem.New;
public static class Path
{
public static readonly char Sep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '\\' : '/';
private static readonly char NotSep = Environment.OSVersion.Platform == PlatformID.Win32NT ? '/' : '\\' ;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string Concat(string path, string addition) => $"{path}{Sep}{addition}";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string Concat(params string[] parts) => StringConverter.MergeToString(Sep, parts);
public static string FixSeparators(string path)
{
var chars = path.ToCharArray();
int length = path.Length;
for(int i=0; i<length; i++)
if (chars[i] == NotSep)
chars[i] = Sep;
return chars.ToString();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string Resolve(params string[] parts) => FixSeparators(Concat(parts));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string Resolve(string path, string addition) => FixSeparators(Concat(path, addition));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ThrowIfEscapes(string path)
{
if (path.Contains(".."))
throw new Exception($"path <{path}> uses <..>, that's not allowed");
}
}