C# Watch Files in Drive FileSystemWatcher

Thereare many instances that require systems to perform certain tasks when files ordirectories are created or modified. One example of this is an import systemthat pulls flat files into a database. In this instance, a program must monitora directory for newly created files. When a file is created, the program mustpick up the file, parse it, and insert it into the database. Many timesthis type of functionality is accomplished by “polling” the directoryand enumerating any new files that have been created since the last poll. Withthe introduction of the .NETFramework, Microsoft has provided developers with an alternative to constantly polling adirectory for new files–the FileSystemWatcher object.

The FileSystemWatcher object does the work of monitoringa directory for you. When a file is created, updated, or deleted, the FileSystemWatcher fires an event to notify you that achange has occurred. This allows your program to know when a new file isavailable almost immediately after the file is created. Immediatenotification of changes allows your system to work much more efficiently sinceyou’re not constantly polling the directory for changes, and there is no timelapse between scans of the directory.

The FileSystemWatcher basics

There are a few basic properties and events you need to familiarize yourself with before working with the FileSystemWatcher object. Undoubtedly, the mostimportant property of this object is the “EnableRaisingEvents” property. This property determines whether ornot the object will fire events when it receives a change notification. If EnableRaisingEvents is set to false, the object willnot fire the change events. If it is set to true, the events will be fired.Below are several other important properties/events that you will use as youtake advantage of FileSystemWatcher:

Properties:

Path — This property tells the FileSystemWatcher which path it needs to monitor. For example, if we set this property to “C:\Temp\”, all changes in that directory would be monitored.
IncludeSubDirectories — This property indicates whether or not the FileSystemWatcher should monitor subdirectories for changes.
Filter — This property allows you to filter the changes for certain file types. For example, if we wanted to be notified only when TXT files are modified/created/deleted, we would set this property to “*.java”. This property is very handy when working with high-traffic or large directories.
Events:

Changed — This event is fired when a file has been modified in the directory thatis being monitored. It is important to note that this event may be fired multiple times, even when only one change to the content of the file has occurred. This is due to other properties of the file changing as the file is saved.
Created — This event is fired when a file is created in the directory that is being monitored. If you are planning to use this event to move the file that was created, you must write some error handling in your event handler that can handle situations where the file is currently in use by another process. The reason for this is that the Created event can be fired before the process that created the file has released the file. This will cause exceptions to be thrown if you have not prepared the code correctly.
Deleted — This event is fired when a file is deleted in the directory that is being watched.
Renamed — This event is fired when a file is renamed in the directory that is being watched.
Note: None of these events will be firedif you do not have EnableRaisingEvents set to true. If at any point your FileSystemWatcher does not seem to be working, check EnableRaisingEvents first to make sure it is set totrue.

Event processing

Whenan event handler is called by the FileSystemWatcher, it contains two arguments–an object called “sender”,and a FileSystemEventArgs object called “e”. Theargument we’re interested in is the FileSystemEventArgs argument. This object contains information aboutwhat caused the event to be fired. The following is available from the FileSystemEventArgs object:

Properties:

Name — This property contains the name of the file that caused the event to be fired. It DOES NOT contain that path to the file–only the file or directory name that caused the event to be fired.
ChangeType — This is a type of WatcherChangeTypes and indicates which type of event was fired. Valid values are:
Changed
Created
Deleted
Renamed
FullPath — This contains the full path to the file that caused the event to fire. It includes the filename and the directory name.
Example code


using System;
using System.IO;

public class DirectoryChangeListener
{
    public DirectoryChangeListener()
	{
	}
    
    public static void Main(){

       FileSystemWatcher watcher = new FileSystemWatcher();
       Console.WriteLine("Started....");

      //watcher.SynchronizingObject = this;

         watcher.Path =Path.GetDirectoryName(@"C:\Program Files");
         //watcher.Filter = Path.GetFileName(@"c:\a.txt");
         watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size;
         watcher.IncludeSubdirectories = true;
          watcher.Deleted += new System.IO.FileSystemEventHandler(OnDelete);
          watcher.Renamed += new System.IO.RenamedEventHandler(OnRenamed);
          watcher.Changed += new System.IO.FileSystemEventHandler(OnChanged);
          watcher.Created += new System.IO.FileSystemEventHandler(OnCreate);
          watcher.EnableRaisingEvents = true;

          Console.ReadLine();
       }
     
      public static void OnChanged(object source, FileSystemEventArgs e) {
         Console.WriteLine("File: {0} {1}", e.FullPath, e.ChangeType.ToString());
      }
 
 
      public static void OnRenamed(object source, RenamedEventArgs e){
         Console.WriteLine("File renamed from {0} to {1}", e.OldName, e.FullPath);
      }
 
 
      public static void OnDelete(object source, FileSystemEventArgs e)
      {
          Console.WriteLine("File: {0} Deleted", e.FullPath);
      }
      public static void OnCreate(object source, FileSystemEventArgs e)
      {
          Console.WriteLine("File: {0} Created", e.FullPath);
      }
  
   }

AES Encryption Sample in C# (CSharp)

Recently I have written a post on Encryption and compression in Java. Now i had similar requirement to do in CSharp( I work on Distrubuted systems which are in Different Technology Stack). Here is the sample which does AES Encryption of files/text etc using a key

using System;
using System.IO;
using System.Security.Cryptography; 

//
// Sample encrypt/decrypt functions
// Parameter checks and error handling
// are ommited for better readability
//  http://www.codeproject.com/Articles/5719/Simple-encrypting-and-decrypting-data-in-C
public class AESEncryptionUtility
{
	static int  Main(string[] args)
    {
		if (args.Length < 2)
            {
                Console.WriteLine("Usage: AESEncryptionUtility infile outFile");
                return 1;
            }
			string infile = args[0];
            string outfile = args[1];
			//string keyfile = args[2];
			//var key = File.ReadAllBytes(keyfile);
			Encrypt(infile,outfile,"test");
			Decrypt(outfile,"_decrypted"+infile,"test");
			return 0;

	}

    // Encrypt a byte array into a byte array using a key and an IV
    public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)
    {
        // Create a MemoryStream to accept the encrypted bytes
        MemoryStream ms = new MemoryStream();
        // Create a symmetric algorithm.
        // We are going to use Rijndael because it is strong and
        // available on all platforms.
        // You can use other algorithms, to do so substitute the
        // next line with something like
        //      TripleDES alg = TripleDES.Create();
        Rijndael alg = Rijndael.Create();
        // Now set the key and the IV.
        // We need the IV (Initialization Vector) because
        // the algorithm is operating in its default
        // mode called CBC (Cipher Block Chaining).
        // The IV is XORed with the first block (8 byte)
        // of the data before it is encrypted, and then each
        // encrypted block is XORed with the
        // following block of plaintext.
        // This is done to make encryption more secure.
        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure.
        alg.Key = Key;
        alg.IV = IV;
        // Create a CryptoStream through which we are going to be
        // pumping our data.
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream and the output will be written
        // in the MemoryStream we have provided.
        CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
        // Write the data and make it do the encryption
        cs.Write(clearData, 0, clearData.Length);
        // Close the crypto stream (or do FlushFinalBlock).
        // This will tell it that we have done our encryption and
        // there is no more data coming in,
        // and it is now a good time to apply the padding and
        // finalize the encryption process.
        cs.Close();
        // Now get the encrypted data from the MemoryStream.
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way.
        byte[] encryptedData = ms.ToArray();
        return encryptedData;
    } 

    // Encrypt a string into a string using a password
    //    Uses Encrypt(byte[], byte[], byte[])
    public static string Encrypt(string clearText, string Password)
    {
        // First we need to turn the input string into a byte array.
        byte[] clearBytes =
          System.Text.Encoding.Unicode.GetBytes(clearText);
        // Then, we need to turn the password into Key and IV
        // We are using salt to make it harder to guess our key
        // using a dictionary attack -
        // trying to guess a password by enumerating all possible words.
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
        // Now get the key/IV and do the encryption using the
        // function that accepts byte arrays.
        // Using PasswordDeriveBytes object we are first getting
        // 32 bytes for the Key
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV.
        // IV should always be the block size, which is by default
        // 16 bytes (128 bit) for Rijndael.
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size.
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes.
        byte[] encryptedData = Encrypt(clearBytes,
                 pdb.GetBytes(32), pdb.GetBytes(16)); 

        // Now we need to turn the resulting byte array into a string.
        // A common mistake would be to use an Encoding class for that.
        //It does not work because not all byte values can be
        // represented by characters.
        // We are going to be using Base64 encoding that is designed
        //exactly for what we are trying to do.
        return Convert.ToBase64String(encryptedData);
    }

    // Encrypt bytes into bytes using a password
    //    Uses Encrypt(byte[], byte[], byte[])
    public static byte[] Encrypt(byte[] clearData, string Password)
    {
        // We need to turn the password into Key and IV.
        // We are using salt to make it harder to guess our key
        // using a dictionary attack -
        // trying to guess a password by enumerating all possible words.
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}); 

        // Now get the key/IV and do the encryption using the function
        // that accepts byte arrays.
        // Using PasswordDeriveBytes object we are first getting
        // 32 bytes for the Key
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV.
        // IV should always be the block size, which is by default
        // 16 bytes (128 bit) for Rijndael.
        // If you are using DES/TripleDES/RC2 the block size is 8
        // bytes and so should be the IV size.
        // You can also read KeySize/BlockSize properties off the
        // algorithm to find out the sizes.
        return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));
    }

    // Encrypt a file into another file using a password
    public static void Encrypt(string fileIn,
                string fileOut, string Password)
    {
        // First we are going to open the file streams
        FileStream fsIn = new FileStream(fileIn,
            FileMode.Open, FileAccess.Read);
        FileStream fsOut = new FileStream(fileOut,
            FileMode.OpenOrCreate, FileAccess.Write);
        // Then we are going to derive a Key and an IV from the
        // Password and create an algorithm
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
        Rijndael alg = Rijndael.Create();
        alg.Key = pdb.GetBytes(32);
        alg.IV = pdb.GetBytes(16);
        // Now create a crypto stream through which we are going
        // to be pumping data.
        // Our fileOut is going to be receiving the encrypted bytes.
        CryptoStream cs = new CryptoStream(fsOut,
            alg.CreateEncryptor(), CryptoStreamMode.Write); 

        // Now will will initialize a buffer and will be processing
        // the input file in chunks.
        // This is done to avoid reading the whole file (which can
        // be huge) into memory.
        int bufferLen = 4096;
        byte[] buffer = new byte[bufferLen];
        int bytesRead;
        do {
            // read a chunk of data from the input file
            bytesRead = fsIn.Read(buffer, 0, bufferLen);
            // encrypt it
            cs.Write(buffer, 0, bytesRead);
        } while(bytesRead != 0);
        // close everything
        // this will also close the unrelying fsOut stream
        cs.Close();
        fsIn.Close();
    } 

    // Decrypt a byte array into a byte array using a key and an IV
    public static byte[] Decrypt(byte[] cipherData,
                                byte[] Key, byte[] IV)
    {
        // Create a MemoryStream that is going to accept the
        // decrypted bytes
        MemoryStream ms = new MemoryStream();
        // Create a symmetric algorithm.
        // We are going to use Rijndael because it is strong and
        // available on all platforms.
        // You can use other algorithms, to do so substitute the next
        // line with something like
        //     TripleDES alg = TripleDES.Create();
        Rijndael alg = Rijndael.Create();
        // Now set the key and the IV.
        // We need the IV (Initialization Vector) because the algorithm
        // is operating in its default
        // mode called CBC (Cipher Block Chaining). The IV is XORed with
        // the first block (8 byte)
        // of the data after it is decrypted, and then each decrypted
        // block is XORed with the previous
        // cipher block. This is done to make encryption more secure.
        // There is also a mode called ECB which does not need an IV,
        // but it is much less secure.
        alg.Key = Key;
        alg.IV = IV;
        // Create a CryptoStream through which we are going to be
        // pumping our data.
        // CryptoStreamMode.Write means that we are going to be
        // writing data to the stream
        // and the output will be written in the MemoryStream
        // we have provided.
        CryptoStream cs = new CryptoStream(ms,
            alg.CreateDecryptor(), CryptoStreamMode.Write);
        // Write the data and make it do the decryption
        cs.Write(cipherData, 0, cipherData.Length);
        // Close the crypto stream (or do FlushFinalBlock).
        // This will tell it that we have done our decryption
        // and there is no more data coming in,
        // and it is now a good time to remove the padding
        // and finalize the decryption process.
        cs.Close();
        // Now get the decrypted data from the MemoryStream.
        // Some people make a mistake of using GetBuffer() here,
        // which is not the right way.
        byte[] decryptedData = ms.ToArray();
        return decryptedData;
    }

    // Decrypt a string into a string using a password
    //    Uses Decrypt(byte[], byte[], byte[])
    public static string Decrypt(string cipherText, string Password)
    {
        // First we need to turn the input string into a byte array.
        // We presume that Base64 encoding was used
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        // Then, we need to turn the password into Key and IV
        // We are using salt to make it harder to guess our key
        // using a dictionary attack -
        // trying to guess a password by enumerating all possible words.
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65,
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
        // Now get the key/IV and do the decryption using
        // the function that accepts byte arrays.
        // Using PasswordDeriveBytes object we are first
        // getting 32 bytes for the Key
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV.
        // IV should always be the block size, which is by
        // default 16 bytes (128 bit) for Rijndael.
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size.
        // You can also read KeySize/BlockSize properties off
        // the algorithm to find out the sizes.
        byte[] decryptedData = Decrypt(cipherBytes,
           pdb.GetBytes(32), pdb.GetBytes(16));
        // Now we need to turn the resulting byte array into a string.
        // A common mistake would be to use an Encoding class for that.
        // It does not work
        // because not all byte values can be represented by characters.
        // We are going to be using Base64 encoding that is
        // designed exactly for what we are trying to do.
        return System.Text.Encoding.Unicode.GetString(decryptedData);
    }

    // Decrypt bytes into bytes using a password
    //    Uses Decrypt(byte[], byte[], byte[])
    public static byte[] Decrypt(byte[] cipherData, string Password)
    {
        // We need to turn the password into Key and IV.
        // We are using salt to make it harder to guess our key
        // using a dictionary attack -
        // trying to guess a password by enumerating all possible words.
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
        // Now get the key/IV and do the Decryption using the
        //function that accepts byte arrays.
        // Using PasswordDeriveBytes object we are first getting
        // 32 bytes for the Key
        // (the default Rijndael key length is 256bit = 32bytes)
        // and then 16 bytes for the IV.
        // IV should always be the block size, which is by default
        // 16 bytes (128 bit) for Rijndael.
        // If you are using DES/TripleDES/RC2 the block size is
        // 8 bytes and so should be the IV size.
        // You can also read KeySize/BlockSize properties off the
        // algorithm to find out the sizes.
        return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));
    }

    // Decrypt a file into another file using a password
    public static void Decrypt(string fileIn,
                string fileOut, string Password)
    {
        // First we are going to open the file streams
        FileStream fsIn = new FileStream(fileIn,
                    FileMode.Open, FileAccess.Read);
        FileStream fsOut = new FileStream(fileOut,
                    FileMode.OpenOrCreate, FileAccess.Write);
        // Then we are going to derive a Key and an IV from
        // the Password and create an algorithm
        PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
            new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d,
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});
        Rijndael alg = Rijndael.Create();
        alg.Key = pdb.GetBytes(32);
        alg.IV = pdb.GetBytes(16);
        // Now create a crypto stream through which we are going
        // to be pumping data.
        // Our fileOut is going to be receiving the Decrypted bytes.
        CryptoStream cs = new CryptoStream(fsOut,
            alg.CreateDecryptor(), CryptoStreamMode.Write);
        // Now will will initialize a buffer and will be
        // processing the input file in chunks.
        // This is done to avoid reading the whole file (which can be
        // huge) into memory.
        int bufferLen = 4096;
        byte[] buffer = new byte[bufferLen];
        int bytesRead;
        do {
            // read a chunk of data from the input file
            bytesRead = fsIn.Read(buffer, 0, bufferLen);
            // Decrypt it
            cs.Write(buffer, 0, bytesRead);
        } while(bytesRead != 0);
        // close everything
        cs.Close(); // this will also close the unrelying fsOut stream
        fsIn.Close();
    }
 }