diff --git a/Lesson_7/Task_1/Classes/CopyDirectory.cs b/Lesson_7/Task_1/Classes/CopyDirectory.cs new file mode 100644 index 0000000..2d4a63b --- /dev/null +++ b/Lesson_7/Task_1/Classes/CopyDirectory.cs @@ -0,0 +1,39 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class CopyDirectory : ICopyDirectory +{ + public static void Copy(string sourceDir, string destinationDir, bool recursive) + { + // Get information about the source directory + var dir = new DirectoryInfo(sourceDir); + + // Check if the source directory exists + if (!dir.Exists) + throw new DirectoryNotFoundException($"Source directory not found: {dir.FullName}"); + + // Cache directories before we start copying + DirectoryInfo[] dirs = dir.GetDirectories(); + + // Create the destination directory + Directory.CreateDirectory(destinationDir); + + // Get the files in the source directory and copy to the destination directory + foreach (FileInfo file in dir.GetFiles()) + { + string targetFilePath = Path.Combine(destinationDir, file.Name); + file.CopyTo(targetFilePath); + } + + // If recursive and copying subdirectories, recursively call this method + if (recursive) + { + foreach (DirectoryInfo subDir in dirs) + { + string newDestinationDir = Path.Combine(destinationDir, subDir.Name); + Copy(subDir.FullName, newDestinationDir, true); + } + } + } +} diff --git a/Lesson_7/Task_1/Classes/Operations.cs b/Lesson_7/Task_1/Classes/Operations.cs new file mode 100644 index 0000000..2d3a1e1 --- /dev/null +++ b/Lesson_7/Task_1/Classes/Operations.cs @@ -0,0 +1,56 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class Operations : IOperations +{ + + public static void GetFileInfo(string path) + { + var info = new FileInfo(path); + + Console.WriteLine($"Name: {info.Name}"); + Console.WriteLine($"Creation time: {info.CreationTime}"); + Console.WriteLine($"Length: {info.Length}"); + } + + public static async Task CopyAsync(string source, string destination, bool keepSource=true) + { + try + { + destination = Validation.Check(source, destination); + } + catch (PathConflictException) + { + Console.WriteLine("Conflict."); + return; + } + + bool exists = await Task.Run(() => Directory.Exists(source) || File.Exists(source)); + + if (exists) + if (keepSource) + { + if (Directory.Exists(source)) + await Task.Run(() => CopyDirectory.Copy(source, destination, true)); + else if (File.Exists(source)) + await Task.Run(() => File.Copy(source, destination)); + } + else + { + await Task.Run(() => Directory.Move(source, destination)); + } + else + Console.WriteLine("Not found."); + } + + public static async Task DeleteAsync(string path) + { + if (Directory.Exists(path)) + await Task.Run(() => Directory.Delete(path, true)); + else if (File.Exists(path)) + await Task.Run(() => File.Delete(path)); + else + Console.WriteLine("Not found."); + } +} \ No newline at end of file diff --git a/Lesson_7/Task_1/Classes/PathConflictException.cs b/Lesson_7/Task_1/Classes/PathConflictException.cs new file mode 100644 index 0000000..82d2fcd --- /dev/null +++ b/Lesson_7/Task_1/Classes/PathConflictException.cs @@ -0,0 +1,19 @@ +namespace Lesson5.Classes; + +[Serializable] +public class PathConflictException : Exception +{ + public PathConflictException () + { + } + + public PathConflictException (string message) + : base(message) + { + } + + public PathConflictException (string message, Exception innerException) + : base(message, innerException) + { + } +} diff --git a/Lesson_7/Task_1/Classes/ReadFile.cs b/Lesson_7/Task_1/Classes/ReadFile.cs new file mode 100644 index 0000000..1e2e591 --- /dev/null +++ b/Lesson_7/Task_1/Classes/ReadFile.cs @@ -0,0 +1,17 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class ReadFile : IReadFile +{ + public static async Task ReadByPathAsync(string path) + { + if (File.Exists(path)) + { + var data = await File.ReadAllTextAsync(path); + Console.WriteLine(data); + } + else + Console.WriteLine("No such file exists."); + } +} diff --git a/Lesson_7/Task_1/Classes/UserInput.cs b/Lesson_7/Task_1/Classes/UserInput.cs new file mode 100644 index 0000000..30aa9a0 --- /dev/null +++ b/Lesson_7/Task_1/Classes/UserInput.cs @@ -0,0 +1,17 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class UserInput : IUserInput +{ + public static string AskStringInput(string prompt) + { + while (true) + { + Console.Write(prompt); + string? input = Console.ReadLine(); + if (!string.IsNullOrEmpty(input)) + return input; + } + } +} diff --git a/Lesson_7/Task_1/Classes/Validation.cs b/Lesson_7/Task_1/Classes/Validation.cs new file mode 100644 index 0000000..534592d --- /dev/null +++ b/Lesson_7/Task_1/Classes/Validation.cs @@ -0,0 +1,20 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class Validation : IValidation +{ + public static string Check(string source, string destination) + { + if (File.Exists(destination)) + throw new PathConflictException(); + + if (Directory.Exists(destination)) + destination = Path.Combine(destination, Path.GetFileName(source)); + + if (File.Exists(destination) || Directory.Exists(destination)) + throw new PathConflictException(); + + return destination; + } +} diff --git a/Lesson_7/Task_1/Classes/WorkWithFileSystem.cs b/Lesson_7/Task_1/Classes/WorkWithFileSystem.cs new file mode 100644 index 0000000..15dccba --- /dev/null +++ b/Lesson_7/Task_1/Classes/WorkWithFileSystem.cs @@ -0,0 +1,43 @@ +namespace Lesson5.Classes; + +using Lesson5.Interfaces; + +public class WorkWithFileSystem : IWorkWithFileSystem +{ + public static async Task GetDirectoryFilesAsync(string path) + { + var current = new DirectoryInfo(path); + var dirs = await Task.Run(() => Directory.GetDirectories(current.FullName)); + var files = await Task.Run(() => Directory.GetFiles(current.FullName)); + + foreach (var dir in dirs) + { + Console.WriteLine(dir.Split('\\').Last() + "/"); + } + foreach (var file in files) + { + Console.WriteLine(file.Split('\\').Last()); + } + } + + public static string Cd(string name, string current) + { + if (name == "..") + { + var info = new DirectoryInfo(current); + + var parent = info.Parent; + + return parent is not null ? parent.FullName : current; + } + + var dir = Path.Combine(current, name); + + if (Directory.Exists(dir)) + { + return dir; + } + + return current; + } +} diff --git a/Lesson_7/Task_1/Interfaces/ICopyDirectory.cs b/Lesson_7/Task_1/Interfaces/ICopyDirectory.cs new file mode 100644 index 0000000..bb31be9 --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/ICopyDirectory.cs @@ -0,0 +1,6 @@ +namespace Lesson5.Interfaces; + +public interface ICopyDirectory +{ + static void Copy(string sourceDir, string destinationDir, bool recursive) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Interfaces/IOperations.cs b/Lesson_7/Task_1/Interfaces/IOperations.cs new file mode 100644 index 0000000..5ecc02e --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/IOperations.cs @@ -0,0 +1,8 @@ +namespace Lesson5.Interfaces; + +public interface IOperations +{ + static void GetFileInfo(string path) => throw new NotImplementedException(); + static Task CopyAsync(string source, string destination, bool keepSource=true) => throw new NotImplementedException(); + static Task DeleteAsync(string path) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Interfaces/IReadFile.cs b/Lesson_7/Task_1/Interfaces/IReadFile.cs new file mode 100644 index 0000000..4a6b700 --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/IReadFile.cs @@ -0,0 +1,6 @@ +namespace Lesson5.Interfaces; + +public interface IReadFile +{ + static Task ReadByPathAsync(string path) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Interfaces/IUserInput.cs b/Lesson_7/Task_1/Interfaces/IUserInput.cs new file mode 100644 index 0000000..622883b --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/IUserInput.cs @@ -0,0 +1,6 @@ +namespace Lesson5.Interfaces; + +public interface IUserInput +{ + static string AskStringInput(string prompt) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Interfaces/IValidation.cs b/Lesson_7/Task_1/Interfaces/IValidation.cs new file mode 100644 index 0000000..4c04bb5 --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/IValidation.cs @@ -0,0 +1,6 @@ +namespace Lesson5.Interfaces; + +public interface IValidation +{ + static string Check(string source, string destination) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Interfaces/IWorkWithFileSystem.cs b/Lesson_7/Task_1/Interfaces/IWorkWithFileSystem.cs new file mode 100644 index 0000000..ca6679f --- /dev/null +++ b/Lesson_7/Task_1/Interfaces/IWorkWithFileSystem.cs @@ -0,0 +1,7 @@ +namespace Lesson5.Interfaces; + +public interface IWorkWithFileSystem +{ + static Task GetDirectoryFilesAsync(string path) => throw new NotImplementedException(); + static void Cd(string name, string current) => throw new NotImplementedException(); +} diff --git a/Lesson_7/Task_1/Program.cs b/Lesson_7/Task_1/Program.cs new file mode 100644 index 0000000..26491a7 --- /dev/null +++ b/Lesson_7/Task_1/Program.cs @@ -0,0 +1,60 @@ +/* +* Lesson 5 Task 1: a file manager +* Author: Stanislav Mykhailenko, parts of code used from DanyilMykytenko's repository +* License: Unlicense +*/ + +using Lesson5.Classes; +using Lesson5.Interfaces; + +var dir = Directory.GetCurrentDirectory(); +string? command; + +while (true) +{ + Console.WriteLine(@"cd - change directory +dir - show current directory contents +open - read data +mv - move data +rm - remove data +cp - copy data +info - get data info +"); + + Console.Write("{0}> ", dir); + + command = Console.ReadLine(); + + switch (command) + { + case "cd": + dir = WorkWithFileSystem.Cd(UserInput.AskStringInput("Enter the directory name: "), dir); + break; + case "dir": + await WorkWithFileSystem.GetDirectoryFilesAsync(dir); + break; + case "open": + await ReadFile.ReadByPathAsync(UserInput.AskStringInput("Enter the file name: ")); + break; + case "mv": + string moveSource = Path.Combine(dir, UserInput.AskStringInput("Enter the source: ")); + string moveDestination = Path.Combine(dir, UserInput.AskStringInput("Enter the destination: ")); + await Operations.CopyAsync(moveSource, moveDestination, false); + break; + case "rm": + string path = Path.Combine(dir, UserInput.AskStringInput("Enter the file or directory to delete: ")); + await Operations.DeleteAsync(path); + break; + case "cp": + string copySource = Path.Combine(dir, UserInput.AskStringInput("Enter the source: ")); + string copyDestination = Path.Combine(dir, UserInput.AskStringInput("Enter the destination: ")); + await Operations.CopyAsync(copySource, copyDestination); + break; + case "info": + Operations.GetFileInfo(UserInput.AskStringInput("Enter the file name: ")); + break; + default: + Console.WriteLine("Unknown command"); + break; + } +} diff --git a/Lesson_7/Task_1/Task_1.csproj b/Lesson_7/Task_1/Task_1.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/Lesson_7/Task_1/Task_1.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + +