Creating directory if directory exists - c#

I have the following directory:
\\192.168.255.86\Add-in\Requests\MyFolder1
If this directory exists (there is already a folder on the specified path) I need to create the following:
\\192.168.255.86\Add-in\Requests\MyFolder1 (1)
If directory still exists I need to create another directory:
\\192.168.255.86\Add-in\Requests\MyFolder1 (2)
and so on.
I did it using while-loop in the following method:
public static string CreateDirectory(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
return path;
}
int i = 1;
while (Directory.Exists(path + $" ({i})"))
{
i++;
}
path += $" ({i})";
Directory.CreateDirectory(path);
return path;
}
How to make it using recursion?

You don't need recursion here. All you want is create new directory with next available name (by adding number).
A slightly refactored method can looks like this:
public string NextDirectory(string path)
{
var dir = path;
int n = 1;
while (Directory.Exists(dir))
dir = $"{path} ({n++})";
Directory.CreateDirectory(dir);
return dir;
}

If you insist on using recursion, this should be nice and elegant:
public static string CreateDirectory(string path, int suffix = 0)
{
string directoryPath = DirectoryPath(path, suffix);
if (!CreateDirectory(directoryPath))
return CreateDirectory(path, i + 1);
return directoryPath;
}
private static bool CreateDirectory(string path)
{
if (Directory.Exists(path))
return false;
Directory.CreateDirectory(path);
return true;
}
private static string DirectoryPath(string path, int suffix)
{
return $"{path}{(suffix > 0 ? $" ({suffix})" : string.Empty)}";
}
But if you already have 'MyFolder1 (214)' your call stack might be immense!
Maybe this is a slightly neater way to do the while loop (but essentially the same):
public static string CreateDirectory(string path)
{
string createPath = GetUniquePath(path);
Directory.CreateDirectory(createPath);
return createPath;
}
private static string GetUniquePath(string path)
{
string result = path;
int i = 1;
while (Directory.Exists(result))
result = $"{path} ({i++})";
return result;
}

You can use this:
public static string CreateDirectory(string path, int i)
{
if (i>0)
{
if (Directory.Exists(path + $" ({i})"))
return CreateDirectory(path,++i);
else
{
Directory.CreateDirectory(path + $" ({i})"));
return path + $" ({i})";
}
}
else
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
return path;
}
else
return CreateDirectory(path,1);
}

Related

How to prevent recursive in copying files and dirs?

I bumped into the problem with copying files/dirs. Been struggling almost for whole day.
I have to copy from root dir files and its dires with files and subdirs.
Actually, i've made something. However, every time i run in the stackoverflow error.
abstract class SystemOperations {
public virtual void SearchFiles() { }
public virtual void SearchDirectories() { }
public abstract void CreateDirectory(string DIR);
public abstract void CloneContent(string DIR);
public abstract void CreateJSON(string DIR);
public void ExecuteCopying(string DIR) {
CreateDirectory(DIR);
CloneContent(DIR);
CreateJSON(DIR);
}
}
class FileOperations : SystemOperations {
DirectoryInfo _MainPath;
public DirectoryInfo MainPath {
get { return _MainPath; }
set { _MainPath = value; }
}
public FileOperations(DirectoryInfo MainPath) {
this.MainPath = MainPath;
}
#region Unnecessary for current task
public override void SearchFiles() {
string path = "";
FileInfo[] files = MainPath.GetFiles();
foreach (FileInfo file in files) {
path = file.Name;
}
}
public override void SearchDirectories() {
string path = "";
DirectoryInfo[] directories = MainPath.GetDirectories();
foreach (DirectoryInfo directory in directories) {
path = directory.Name;
}
}
#endregion
public override void CreateDirectory(string DIR) {
string newFolder = Path.Combine(MainPath + "", DIR);
Directory.CreateDirectory(newFolder);
}
public override void CloneContent(string DIR) {
foreach (var directory in Directory.GetDirectories(MainPath + "")) {
string dir = Path.GetFileName(directory);
CloneContent(Path.Combine(MainPath + "", dir));
}
foreach (var file in Directory.GetFiles(MainPath + "")) {
File.Copy(file, Path.Combine(MainPath + "", Path.GetFileName(file)), true);
}
}
public override void CreateJSON(string DIR) {
if (!Directory.Exists(DIR)) {
var asd = new DirectoryInfo(DIR);
}
}
}
class Program {
static void Main() {
SystemOperations task = new FileOperations(new DirectoryInfo(#"D:\\LAK"));
task.ExecuteCopying("COPY");
}
}
So, the function CloneContent has to copy in each dir/subdirs files. But its recursive func and as i written above, i run to the error. And dont know how to fix this one. Thank u!
There is some kind of problem with the way you are trying to determine which directory you need to search next, the use of MainPath looks wrong to me.
Personally i also always prefer to have a secondary stop condition to avoid a StackOverflowException, like the maxrunCount i use below.
If you want a recursive directory lookup you should rewrite your code to something like
void Main()
{
string MainPath = "D:\\LAK";
// unless your directory is actually named \LAK:) you should use either #"D:\LAK" or "d:\\LAK"
CloneContent(MainPath,1000);
}
public void CloneContent(string directoryToSearch, int maxrunCount)
{
if(maxrunCount==0)
return;
System.Diagnostics.Debug.Print(directoryToSearch);
string[] directories = null;
try
{
directories = Directory.GetDirectories(directoryToSearch);
}
catch(UnauthorizedAccessException ex) {
System.Diagnostics.Debug.Print($"No access to dir {directoryToSearch}");
directories = new string[0];
}
// ensure you have access to the current directoryToSearch
foreach (var directory in directories)
{
CloneContent(directory,--maxrunCount);
}
System.Diagnostics.Debug.Print($"cloning {directoryToSearch}");
// .... do the actual cloning here,
// you will end up here when there are no more subdirectories on the current branch
}
For a recursive method to work, it must have at least one "exit" condition - the point at which it's done its job and can unwind the stack. In our case, it would be when there are no more direcories or files to copy from the source to the destination.
One way of writing this method would take in a source directory and a destination directory, and then it can recursively call itself for each sub-directory:
public static void CloneContent(string sourceDir, string destDir)
{
// If the source directory doesn't exist, return
if (!Directory.Exists(sourceDir)) return;
// Create destination if needed
Directory.CreateDirectory(destDir);
// Copy files from this directory to the new path
foreach (string file in Directory.GetFiles(sourceDir))
{
File.Copy(file, Path.Combine(destDir, Path.GetFileName(file)));
}
// Recursively call this method for each sub directory
foreach (string subDir in Directory.GetDirectories(sourceDir))
{
string dirName = Path.GetFileName(subDir);
string newSource = Path.Combine(sourceDir, dirName);
string newDest = Path.Combine(destDir, dirName);
CloneContent(newSource, newDest);
}
}

"Can't create Directory as the directory doesn't exist"

This is my logging.cs, It usually may create the "Log-Folder" and the Datetime.csv into the users Desktop
public static class Logging
{
public static string _Path = $"C:\\Users\\{Environment.UserName}\\Desktop\\Logs\\{DateTime.Now.ToString("dd.MM.yyyy")}.csv";
static StreamWriter _File = new StreamWriter(_Path);
public static void getPath(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
public static void logging(string message)
{
_File.Write(message);
}
}
In my main class, i use the method logging just to enter "Test" into the csv file
class Program
{
static void Main(string[] args)
{
Logging.getPath(Logging._Path);
Logging.logging("Test");
}
}
but when there is no "Logs-Folder", i get the exception that part of the path doesn´t exist. If i create the path manually, i get the exception, that the path already exists, so something's wrong with the If-Statement up in the Logging-class. But i don't know what the heck works wrong
Your path is a file and not a directory. You need to create the directory from your path
String Path = $"C:\\Users\\{Environment.UserName}\\Desktop\\Logs\\{DateTime.Now.ToString("dd.MM.yyyy")}.csv";
String Directory = System.IO.Path.GetDirectoryName(Path);
if (System.IO.Directory.Exists(Directory)==false) {
System.IO.Directory.CreateDirectory(Directory);
}
if (System.IO.File.Exists(Path)==false) {
System.IO.File.Create(Path);
}
Your _Path variable isn't actually a directory, but rather a filename.
You get the Directory with System.IO.Path.GetDirectoryName(_Path)
Your testing if an Directory exists but your giving the path to a File. Here's some code you could use to fix it:
public static string _Path = $"C:\\Users\\{Environment.UserName}\\Desktop\\Logs";
public static string _Filename = $"{DateTime.Now.ToString("dd.MM.yyyy")}.csv";
static StreamWriter _File = new StreamWriter(_File);
Try to take DirectoryPath and FilePath differently.
Move your StreamWriter to method scope so we can close this stream after Write content inside file.
public static class Logging
{
public static string _DirectoryPath = $"C:\\Users\\{Environment.UserName}\\Desktop\\Logs";
public static string _FileName = $"{DateTime.Now.ToString("dd.MM.yyyy")}.csv";
public static void getPath(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
}
public static void logging(string message)
{
StreamWriter _sw = new StreamWriter(_DirectoryPath + "\\" + _FileName);
_sw.Write(message);
_sw.Flush();
_sw.Close();
}
}
And from Program.cs.
Logging.getPath(Logging._DirectoryPath);
Logging.logging("Test");
Output:

Export Visual Studio folder structure into Excel

Is there a way to export Visual Studio "Solution Explorer" structure into excel?
I tried "tree" command and clip it via Windows Command Prompt like this:
but it's little hard to splite to each Excel sells.
I expecting result like this:
so any good idea for it?
Thanks.
Here you have a solution. Preety simple recursive solution to list files in the format you want
public class GetFilesTreeList
{
private static List<Files> files = new List<Files>();
public static void Main(string[] args)
{
var path = #"C:\Users\Lukasz\Desktop";
files.Add(new Files(Path.GetFileName(path), 0));
WriteFilesRec(path, 1);
foreach (var filese in files)
{
Console.WriteLine(filese);
}
}
public class Files {
public int column;
public string name;
public Files(string name, int column)
{
this.column = column;
this.name = name;
}
public override string ToString()
{
return new String('+', column) + name;
}
}
public static void WriteFilesRec(string path, int i) {
DirectoryInfo directory = new DirectoryInfo(path);
foreach(var d in directory.GetDirectories()) {
files.Add(new Files(d.Name, i));
WriteFilesRec(Path.Combine(path, d.Name), i+1);
}
foreach(var f in directory.GetFiles()) {
files.Add(new Files(f.Name, i));
}
}
}

How can i ZipFile.CreateFromDirectory with Log.txt in c#

My code:
public static string Source = #"\\192.168.181.1\Z$\z";
public static string Destination = #"\\192.168.181.1\Z$\z_rar\" + DateTime.Now.ToString("dddd");
public static string Extension = #".zip";
private static void Main(string[] args)
{
if (File.Exists(Destination + Extension))
try
{
File.Delete(Destination + Extension);
ZipFile.CreateFromDirectory(Source, Destination + Extension, CompressionLevel.NoCompression, false);
// here: zipped file details in txt file
}
catch (IOException e)
{
Console.WriteLine(e.Message);
}
else
ZipFile.CreateFromDirectory(Source, Destination + Extension, CompressionLevel.NoCompression, false);
}
How can i create zipped files details save to zipfilename_log.txt file (line by line) in same directory after zipfile.createfromdirectory ?
I solved the problem with the below code:
public static string Source = #"\\192.168.1.11\Z$\z";
public static string Destination = #"\\192.168.1.11\Z$\z_rar\";
public static string NameFormat = DateTime.Now.ToString("dddd");
public static string Extension = #".zip";
public static string LogFilePath = Destination + NameFormat + "_log.txt";
private static void Main(string[] args)
{
File.Delete(Destination + NameFormat + Extension);
File.Delete(LogFilePath);
try
{
ZipFile.CreateFromDirectory(Source, Destination + NameFormat + Extension,
CompressionLevel.NoCompression, false);
var fileListBuilder = new StringBuilder();
using (var za = ZipFile.OpenRead(Destination + NameFormat + Extension))
{
foreach (var zae in za.Entries) fileListBuilder.AppendLine(zae.FullName);
}
File.WriteAllText(LogFilePath, fileListBuilder.ToString());
}
catch (IOException e)
{
File.WriteAllText(LogFilePath, e.ToString());
}
}
Output:
file1.exe
file5.exe
Folder1
Folder2\file3.pdf
Folder2\file4.msi
Thanks to everyone who replies.

String property behaves really weird

I have a settings class like this:
public class Settings
{
string resourcePath;
public string ResourcePath {
get {
return resourcePath + "/";
}
set {
resourcePath = value;
}
}
string texturePath;
public string TexturePath {
get {
string a = resourcePath + "/"; // This is just some debug stuff I did trying to find out wtf is going on
string b = texturePath + "/";
return a + b; // Breakpointing here shows that it is "Content/Textures/"
}
set {
texturePath = value;
}
}
public Settings ()
{
resourcePath = "Content";
texturePath = "Textures";
}
public static Settings CurrentSettings = new Settings();
}
Then I try to get the TexturePath from it, like this:
string path = Settings.CurrentSettings.TexturePath + file;
The string returned by the property is "Content//Content/Textures//"
What am I missing here? Why does it do that? With my knowledge it should return Content/Textures/
Use Path.Combine to work with path.
string path = Path.Combine(Settings.CurrentSettings.TexturePath,file);
and no need to add "/" to your properties.
public string ResourcePath {
get {
return resourcePath;
}
set {
resourcePath = value;
}
}
You might not be balancing the / between the getter and the setter. And you probably are getting some property and then setting another with it - resulting in too many /'s.
You haven't shown the code that produces the results you reported but the following code is highly suspect:
string resourcePath;
public string ResourcePath {
get {
return resourcePath + "/";
}
set {
resourcePath = value;
}
}
It always appends a forward slash on the getter but never removes it in the setter. So the following code:
x.ResourcePath = "abc";
x.ResourcePath = x.ResourcePath + "/def";
x.ResourcePath = x.ResourcePath + "/ghi";
Would set ResourcePath to "abc//def//ghi".
I suspect you are running into something like that.

Categories