Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wait Until File Is Completely Written

When a file is created (FileSystemWatcher_Created) in one directory I copy it to another. But When I create a big (>10MB) file it fails to copy the file, because it starts copying already, when the file is not yet finished creating...
This causes Cannot copy the file, because it's used by another process to be raised. ;(
Any help?

class Program {     static void Main(string[] args)     {         string path = @"D:\levan\FolderListenerTest\ListenedFolder";         FileSystemWatcher listener;          listener = new FileSystemWatcher(path);         listener.Created += new FileSystemEventHandler(listener_Created);         listener.EnableRaisingEvents = true;          while (Console.ReadLine() != "exit") ;     }      public static void listener_Created(object sender, FileSystemEventArgs e)     {         Console.WriteLine                 (                     "File Created:\n"                    + "ChangeType: " + e.ChangeType                    + "\nName: " + e.Name                    + "\nFullPath: " + e.FullPath                 );         File.Copy(e.FullPath, @"D:\levan\FolderListenerTest\CopiedFilesFolder\" + e.Name);         Console.Read();     } } 
like image 318
levi Avatar asked Jun 11 '12 14:06

levi


1 Answers

There is only workaround for the issue you are facing.

Check whether file id in process before starting the process of copy. You can call the following function until you get the False value.

1st Method, copied directly from this answer:

private bool IsFileLocked(FileInfo file) {     FileStream stream = null;      try     {         stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);     }     catch (IOException)     {         //the file is unavailable because it is:         //still being written to         //or being processed by another thread         //or does not exist (has already been processed)         return true;     }     finally     {         if (stream != null)             stream.Close();     }      //file is not locked     return false; } 

2nd Method:

const int ERROR_SHARING_VIOLATION = 32; const int ERROR_LOCK_VIOLATION = 33; private bool IsFileLocked(string file) {     //check that problem is not in destination file     if (File.Exists(file) == true)     {         FileStream stream = null;         try         {             stream = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);         }         catch (Exception ex2)         {             //_log.WriteLog(ex2, "Error in checking whether file is locked " + file);             int errorCode = Marshal.GetHRForException(ex2) & ((1 << 16) - 1);             if ((ex2 is IOException) && (errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION))             {                 return true;             }         }         finally         {             if (stream != null)                 stream.Close();         }     }     return false; } 
like image 129
Romil Kumar Jain Avatar answered Oct 12 '22 16:10

Romil Kumar Jain