• ראיון בJajah
  • ע"י: ירון778
    היי, להלן פתרון תרגיל הבית שחברת גאגא נותנת לאחר מרכז ההערכה בSQLink למשרת C# Automation בהצלחה! (הבחור שבחן אותי בתרגיל היה מתנסה ולא נעים בכלל, אבל תשפטו אותו אתם). ללא טיפול בקבצים: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Security.AccessControl; namespace WindowsFormsApplication3 { public partial class Form1 : Form { private static FileSystemWatcher watcher; private static string targetFolder; public Form1() { InitializeComponent(); } private void sourcePath_TextBox(object sender, EventArgs e) { if (sourcePathValidation(true)) { // Create a new FileSystemWatcher and set its properties. watcher = new FileSystemWatcher(); watcher.Path = sourcePath.Text; } } private void targetPath_TextBox(object sender, EventArgs e) { bool message= true; targetFolder = targetPath.Text; if (!sourcePathValidation(false)) message = false; if (targetPathValidation(message) && !Directory.Exists(targetFolder) ) { Directory.CreateDirectory(targetFolder); } } private void stopButton_Click(object sender, EventArgs e) { if (!sourcePathValidation(false) || !targetPathValidation(false) || watcher==null) { MessageBox.Show("The program did not record anything yet, please press the start button first"); return; } if (watcher != null ) { watcher.EnableRaisingEvents = false; watcher.Dispose(); MessageBox.Show("Stop listening"); } } private void startButton_Click(object sender, EventArgs e) { sourcePath_TextBox(sender, e); targetPath_TextBox(sender, e); if (!sourcePathValidation(false) || !targetPathValidation(false)) { return; } removeReadOnlyAttr(); /* Watch for changes in LastAccess and LastWrite times, and the renaming of files or directories. */ watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // All files. watcher.Filter = "*.*"; watcher.IncludeSubdirectories = true; // Add event handlers. watcher.Changed += new FileSystemEventHandler(OnChanged); watcher.Created += new FileSystemEventHandler(OnChanged); watcher.Deleted += new FileSystemEventHandler(OnDeleted); watcher.Renamed += new RenamedEventHandler(OnRenamed); // Begin watching. watcher.EnableRaisingEvents = true; MessageBox.Show("Start listening"); } // Define the event handlers. private static void OnCreated(object source, FileSystemEventArgs e) { } // Define the event handlers. private static void OnChanged(object source, FileSystemEventArgs e) { string fileNewName; fileNewName = e.Name; string fileExt = Path.GetExtension(e.Name); //Path.GetFileName(e.Name) if (fileExt != ".TXT") { fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt; } string fullSourcePath = Path.Combine(watcher.Path, e.Name); string fullTargetPath = Path.Combine(targetFolder, fileNewName); if (!File.Exists(fullSourcePath)) { return; } /*if (File.Exists(fullTargetPath)) { return; }*/ if (!e.Name.Contains("~") || Path.GetExtension(e.Name) != ".tmp"/* e.Name.Substring(0, 1) != "~"*/) { try { // get the file attributes for file or directory FileAttributes attr = File.GetAttributes(fullSourcePath); //detect whether its a directory or file if ((attr & FileAttributes.Directory) == FileAttributes.Directory) { if (!e.Name.Contains("~") || Path.GetExtension(e.Name) != ".tmp") { WaitReady(fullSourcePath); } copyFolderFromSourceToTarget(fullSourcePath, fullTargetPath); MessageBox.Show("directory"); } else { WaitReady(fullSourcePath); copyFileFromSourceToTarget(fullSourcePath, fullTargetPath); } } catch (FileNotFoundException) { } } deleteAllTmpFilesInWantedFolder(targetFolder); // Specify what is done when a file is changed, created. System.Diagnostics.Debug.WriteLine("File: " + e.Name + " " + e.ChangeType); System.Diagnostics.Debug.WriteLine("File: " + fullTargetPath + " has been updated"); } // Define the event handlers. private static void OnDeleted(object source, FileSystemEventArgs e) { if (e.Name.Contains("~") /*e.Name.Substring(0, 1) == "~"*/ || Path.GetExtension(e.Name)==".tmp" || e.Name.Contains(".pptx")) { return; } // WaitReady(Path.Combine(watcher.Path,e.Name)); string fileNewName; string fileExt = Path.GetExtension(e.Name); fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_deleted" + fileExt; //string noExt = Path.GetFileNameWithoutExtension(e.Name); if (!findFileInFolder(targetFolder, e.Name, ".TXT")) { if (fileExt != ".TXT") { fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_deleted_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt; } string deletedFile = Path.Combine(targetFolder, fileNewName); File.Create(deletedFile).Close(); } else { findOldFileInTargetAndChangeHisName(targetFolder, e.Name, fileNewName, ".TXT"); } deleteAllTmpFilesInWantedFolder(targetFolder); // Specify what is done when a file is deleted. System.Diagnostics.Debug.WriteLine("File: " + e.Name + " " + e.ChangeType); //System.Diagnostics.Debug.WriteLine("File: " + fullTargetPath + " has been deleted"); } private static void OnRenamed(object source, RenamedEventArgs e) { if(/*e.Name.Substring(0, 1) == "~" */e.Name.Contains("~") || Path.GetExtension(e.Name) == ".tmp") { return; } //string fileNewName; string fileNewName = e.Name; string fileExt = Path.GetExtension(e.Name); if (fileExt != ".TXT") { fileNewName = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt; } /* if (File.Exists(Path.Combine(watcher.Path, e.Name))) { WaitReady(Path.Combine(watcher.Path, e.Name)); }*/ if (findOldFileInTargetAndChangeHisName(targetFolder, e.OldName, e.Name, ".TXT")) return; string fullSourcePath = Path.Combine(watcher.Path, e.Name); string fullTargetPath = Path.Combine(targetFolder, fileNewName); try { // To copy a file to another location and // overwrite the destination file if it already exists. File.Copy(fullSourcePath, fullTargetPath, true); } catch(FileNotFoundException){} deleteAllTmpFilesInWantedFolder(targetFolder); // Specify what is done when a file is renamed. //System.Diagnostics.Debug.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath); //System.Diagnostics.Debug.WriteLine("File: "+ fullTargetPath +" has been updated"); } private bool sourcePathValidation(bool message) { if (sourcePath.Text == "" || sourcePath.Text == null) { if (message) { MessageBox.Show("Source path is empty!"); } return false; } if (!isValidPath(sourcePath.Text)) { if (message) { MessageBox.Show("invalide source path"); } return false; } if (!Directory.Exists(sourcePath.Text)) { if (message) { MessageBox.Show("Source Folder does not exist."); } return false; } return true; } private bool targetPathValidation(bool message) { if (targetPath.Text == "" || targetPath.Text == null) { if (message) { MessageBox.Show("Target path is empty!"); } return false; } if (!isValidPath(targetPath.Text)) { if (message) { MessageBox.Show("invalide target path"); } return false; } if (targetPath.Text == sourcePath.Text) { if (message) { MessageBox.Show("Source and target paths are identical"); } return false; } return true; } private void removeReadOnlyAttr() { //Target FileAttributes targetAttr = File.GetAttributes(targetFolder); targetAttr = RemoveAttribute(targetAttr, FileAttributes.ReadOnly); /* | FileAttributes.Archive | FileAttributes.Compressed | FileAttributes.Device | FileAttributes.Directory);*/ File.SetAttributes(targetFolder, targetAttr); // Source FileAttributes sourceAttr = File.GetAttributes(watcher.Path); sourceAttr = RemoveAttribute(sourceAttr, FileAttributes.ReadOnly); File.SetAttributes(watcher.Path, sourceAttr); } private static bool findOldFileInTargetAndChangeHisName(string folder, string oldFileName, string newFileName,string fileExtension) { if ( /*newFileName.Substring(0, 1) == "~" */newFileName.Contains("~") || Path.GetExtension(oldFileName) == ".tmp" || Path.GetExtension(newFileName) == ".tmp") { return false; } if (Directory.Exists(folder)) { string files = Directory.GetFiles(folder); foreach (string s in files) { deleteTmpFile(s); string fileInDir = Path.GetFileNameWithoutExtension(s); string fileExt = Path.GetExtension(s); if (Path.GetFileNameWithoutExtension(oldFileName) == fileInDir) { string destFile = Path.Combine(folder, newFileName); try { if (!File.Exists(destFile)) { //File.Create(destFile); File.Move(s, destFile); } else { MessageBox.Show("update last deleted file with the same file name"); File.Delete(destFile); File.Move(s, destFile); } } catch (FileNotFoundException) { } catch (IOException) { } return true; } if (fileExt != fileExtension) { if (Path.GetFileNameWithoutExtension(oldFileName) == fileInDir.Substring(0, fileInDir.Length - 5)) { fileInDir = Path.GetFileNameWithoutExtension(newFileName) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt; string destFile = Path.Combine(folder, fileInDir); if (!File.Exists(destFile)) { try { File.Move(s, destFile); } catch (UnauthorizedAccessException) { } } else { MessageBox.Show("update last deleted file with the same file name"); try { WaitReady(destFile); File.Delete(destFile); File.Move(s, destFile); } catch(FileNotFoundException){} } return true; } } } return false; //file not found. } return false; //folder does not exist. } private static bool findFileInFolder(string folder, string FileName, string fileExtension) { if (Directory.Exists(folder)) { string files = Directory.GetFiles(folder); foreach (string s in files) { string fileInDir = Path.GetFileNameWithoutExtension(s); string fileExt = Path.GetExtension(s); if (Path.GetFileNameWithoutExtension(FileName) == fileInDir) { return true; } if (fileExt != fileExtension) { if (Path.GetFileNameWithoutExtension(FileName) == fileInDir.Substring(0, fileInDir.Length - 5)) { return true; } } } return false; //file not found. } return false; //folder does not exist. } private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove) { return attributes & ~attributesToRemove; } private static void deleteFileFromTargetFile(string fileName) { string fullTargetPath = Path.Combine(targetFolder, fileName); // Delete a file by using File class static method... if (File.Exists(fullTargetPath)) { // Use a try block to catch IOExceptions, to // handle the case of the file already being // opened by another process. try { System.IO.File.Delete(fullTargetPath); } catch (System.IO.IOException ex) { System.Diagnostics.Debug.WriteLine(ex.Message); return; } } } private static bool isValidPath(string path) { try { path = path.Replace(@"\\", ":"); // to cancel out c:\\\\test.text string temp = Path.GetPathRoot(path); //For cases like: \text.txt if (temp.StartsWith(@"\")) return false; string pt = Path.GetFullPath(path); } catch //(Exception NotSupportedException) // catch specific exception here or not if you want { return false; } return true; } private static void copyFileFromSourceToTarget(string fullSourcePath,string fullTargetPath) { if (!File.Exists(fullTargetPath) ) { File.Create(fullTargetPath).Close(); if (File.Exists(fullSourcePath)) { try { /*using (FileStream fs = File.Create(fullSourcePath)) { fs.Close(); }*/ File.Copy(fullSourcePath, fullTargetPath, true); //File.Open(fullSourcePath, FileMode.Open, FileAccess.Write, FileShare.None).Close(); } catch (IOException) { } } } else { if (File.Exists(fullSourcePath)) { try { File.Delete(fullTargetPath); File.Copy(fullSourcePath, fullTargetPath, true); } catch (UnauthorizedAccessException) { } catch (IOException) { } } } } private static void copyFolderFromSourceToTarget(string fullSourcePath, string fullTargetPath) { if (!Directory.Exists(fullTargetPath)) { Directory.CreateDirectory(fullTargetPath); } } /// <summary> /// Waits until a file can be opened with write permission /// </summary> public static void WaitReady(string fileName) { deleteTmpFile(fileName); for (int i = 0; i < 4; i++) { try { //FileShare.ReadWrite using (Stream stream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read)) { if (stream != null) { System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} ready.", fileName)); break; } } } catch (FileNotFoundException ex) { System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message)); } catch (IOException ex) { System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message)); } catch (UnauthorizedAccessException ex) { System.Diagnostics.Trace.WriteLine(string.Format("Output file {0} not yet ready ({1})", fileName, ex.Message)); } System.Threading.Thread.Sleep(3000); } //File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite).Dispose(); } private static void deleteTmpFile(string tmpFile) { try { tmpFile = Path.GetTempFileName(); // Use temporary file. } finally { if (tmpFile != null) { try { File.Delete(tmpFile); } catch (IOException) { } catch (UnauthorizedAccessException) { } } } } private static void deleteAllTmpFilesInWantedFolder(string folder) { string files = Directory.GetFiles(folder); foreach (string s in files) { if (Path.GetExtension(s) == ".tmp" || s.Contains("~")) { File.Delete(s); } } } private void targetPath_TextChanged(object sender, EventArgs e) { } private void Form1_Load(object sender, EventArgs e) { } } } /* if (Directory.Exists(targetFolder)) { string files = Directory.GetFiles(targetFolder); foreach (string s in files) { string fileInDir = Path.GetFileNameWithoutExtension(s); fileExt = Path.GetExtension(s); if (Path.GetFileNameWithoutExtension(e.OldName) == fileInDir) { string destFile = Path.Combine(targetFolder, e.Name); File.Move(s, destFile); return; } else if (fileExt!=".TXT") { if (Path.GetFileNameWithoutExtension(e.OldName) == fileInDir.Substring(0, fileInDir.Length - 5)) { fileInDir = Path.GetFileNameWithoutExtension(e.Name) + "_" + string.Format("{0:HHmm}", DateTime.Now) + fileExt; string destFile = Path.Combine(targetFolder, fileInDir); File.Move(s, destFile); return; } } } }*/