Recently, I felt overly annoyed by my messy download folder on my personal computer. There were too many files, and it was a total mess. I thought to write a simple bot to address this problem.
The solution is a bot that loops the download, desktop, or any other folder and determines the file type for each and every file. Subsequently, it creates a folder for that file type. All files with the same file type will be transferred to this folder and/or organized by date.
We use .Net Core to make it cross-platform, but the same code works well for .Net Framework, .Net Standard, and Xamarin, so it works on every popular device today.
Let's start it by creating a new project and initializing git.
dotnet new console -o “FileOrganizer”git initgit add *.*
.Net provides FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and sub-directories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.
The FileSystemWatcher does not raise events for CDs and DVDs because time stamps and properties cannot change. Remote computers must have one of the required platforms installed for the component to function properly.
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
watcher.Path = WatchPath;
watcher.Filter = "*.*";
watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime;
watcher.Created += OnCreated;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press 'q' to quit.");
while (Console.Read() != 'q') ;
}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
}
We make a directory in an Organized path such as File Type, year, Mount, and then date.
private static void OnCreated(object sender, FileSystemEventArgs e)
{
string watchFilePath = e.FullPath;
string Extension = Path.GetExtension(watchFilePath).Substring(1);
if (orgSubPaths.ContainsKey(Extension.ToLower()))
{
MoveFile(watchFilePath, orgSubPaths[Extension.ToLower()],Extension);
}
else
{
MoveFile(watchFilePath, "UnKnown",Extension);
}
}
private static void MoveFile(string watchFilePath, string orgSubPath,string Extension)
{
DateTime now = DateTime.Now;
string year = now.Year.ToString();
string month = now.ToString("MMMM");
string day = now.ToString("dd");
string FileName = Path.GetFileName(watchFilePath);
string path2ndPart = $@"{orgSubPath}\{year}\{month}\{day}\";
string FullDirectoryPath = Path.Combine(OrgPath, path2ndPart);
Directory.CreateDirectory(FullDirectoryPath);
File.Move(watchFilePath, OrgEdPath);
}
It works fine, but when it overwrites the file with the same name, so we add a check.
string OrgEdPath = Path.Combine(FullDirectoryPath, FileName);
if(File.Exists(OrgEdPath)){
FileName = $"{Path.GetFileNameWithoutExtension(OrgEdPath)}-{now.Minute}{now.Second}.{Extension}";
OrgEdPath = Path.Combine(FullDirectoryPath, FileName);
}
When the file is pressed, it throws an exception. To overcome this problem, we try to reach the file until the file is open to move.
private static bool IsFileLocked(string FilePath, bool del = false)
{
bool locked = false;
try{
FileStream fs = File.Open(FilePath,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.None);
fs.Close();
if(del)
File.Delete(FilePath);
}
catch(Exception){
locked = true;
}
return locked;
}
//so add new lines in MoveFile function.
while(IsFileLocked(watchFilePath) || IsFileLocked(OrgEdPath,true));
File.Move(watchFilePath, OrgEdPath);
So, we have to add a configuration file to add or update information without making changes in code and generate logs of files with time.
string[] Config = File.ReadAllLines("Config.csv");
WatchPath = Config[0].Split(',')[1];
OrgPath = Config[1].Split(',')[1];
orgSubPaths = new Dictionary<string, string>();
for(int i = 2;i < Config.Length;i++)
{
string[] ExtensionOrgSubPath = Config[i].Split(',');
orgSubPaths.Add(ExtensionOrgSubPath[0], ExtensionOrgSubPath[1]);
}
//Add this to end of MoveFunction
File.AppendAllText("Log.csv",$"{now},{watchFilePath},{OrgEdPath}{Environment.NewLine}");
WatchPath,D:\test\watch
OrgPath,D:\test\org
txt,Word processor and text file
zip,Compressed file
7z,Compressed file
rar,Compressed file
csv,Data and database file
bmp,Image file
gif,Image file
jpeg,Image file
jpg,Image file
png,Image file
doc,Word processor and text file
docx,Word processor and text file
rtf,Word processor and text file
mkv,Video file
mp4,Video file
Also published here.