"Can't create Directory as the directory doesn't exist" - c#

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:

Related

How do I Write Error saved in a Logger in my Console in C#

If I have my class
public class File
{
public bool Load(string fileName)
bool returnValue = false;
if (File.Exists(fileName))
{
returnValue = true;
Logger.Info("File found.");
}
else
{
Logger.Error("File does not exists.");
}
return returnValue;
}
I tried in my main Program.cs
class Program
{
static void Main(string[] args)
{
var appender = new log4net.Appender.MemoryAppender();
log4net.Config.BasicConfigurator.Configure(appender);
var logEntries = appender.GetEvents();
File file = new File();
string folderPath = #"C:\User\files\";
string[] files = Directory.GetFiles(folderPath, "*.*", SearchOption.AllDirectories);
foreach(string oneFile in files)
{
file.Load(oneFile);
Console.WriteLine(logEntries);
}
Console.ReadLine();
}
}
My program does not write any log in the console, any one can explain why ?
Maybe I am all wrong. I just don't get it.

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);
}
}

Why am I obtaining "URI formats are not supported" exception trying to write into a log file using C#?

I am writing a method that take a string containing a message and write this string into a log file.
I have done in this way:
internal static void WriteLogFile(string messageLog)
{
if (messageLog == "")
{
messageLog = "L'import delle regole di inoltro è andato a buon fine. Tutte le regole di inoltro sono state inserite";
}
try
{
var filePath = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT");
CultureInfo ci = new CultureInfo("it-IT");
File.WriteAllText(filePath + "log.txt", messageLog);
Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT");
}
catch (Exception ex)
{
throw ex;
}
}
The problem is that when perform this line:
File.WriteAllText(filePath + "log.txt", messageLog);
I am obtaining the following exception:
"URI formats are not supported."
What is wrong? What am I missing? How can I try to fix it?
Because WriteAllText does not support a URI format, and you're using a URI.
Per https://learn.microsoft.com/en-us/dotnet/api/system.io.file.writealltext?view=netframework-4.8, you need to pass it a string path.
As others have suggested, you should use GetPath if you want to create the file locally, or some other method depending where you want the file to go.
Try this class:
using System;
using System.IO;
namespace YourNameSpace.Models
{
public class Logger
{
private Object Locker { get; set; }
public string Path { get; set; }
public Logger(string path)
{
Locker = new Object();
Path = path;
}
public void Log(string message, params object[] args)
{
lock (Locker)
{
string messageToLog = string.Format("{0} - {1}", DateTime.Now, string.Format(message, args));
string path = System.IO.Path.Combine(Path, string.Format("{0}.txt", DateTime.Today.ToString("yyyyMMdd")));
Directory.CreateDirectory(Path);
File.AppendAllLines(path, new string[] { messageToLog });
}
}
}
}
I'm assuming your problem is to write a log file in the same folder as your executable. Try to use the Location property:
var filePath = Assembly.GetEntryAssembly().Location;
That will return a valid path that you can concatenate with the file name, or use Path.Combine method.

Creating directory if directory exists

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);
}

Is there a way to get this C# code to automatically overwrite files?

Is there a way to get this code to automatically overwrite files?
// Requires project reference to Microsoft.VisualBasic
using Microsoft.VisualBasic.FileIO;
class FileProgress
{
static void Main()
{
string sourcePath = #"C:\Users\public\documents\";
string destinationPath = #"C:\testFolder";
FileSystem.CopyDirectory(sourcePath, destinationPath,
UIOption.AllDialogs);
}
}
This is from MSDN
Thanks
Yes.
use this overload of FileSystem.CopyDirectory to overwrite existing files:
public static void CopyDirectory(
string sourceDirectoryName,
string destinationDirectoryName,
bool overwrite
)
So your code becomes:
// Requires project reference to Microsoft.VisualBasic
using Microsoft.VisualBasic.FileIO;
class FileProgress
{
static void Main()
{
string sourcePath = #"C:\Users\public\documents\";
string destinationPath = #"C:\testFolder";
FileSystem.CopyDirectory(sourcePath, destinationPath, True);
}
}

Categories