#region License and Copyright /* ------------------------------------------------------------------------- * Dotnet Commons IO * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the * * Free Software Foundation, Inc., * 59 Temple Place, * Suite 330, * Boston, * MA 02111-1307 * USA * * ------------------------------------------------------------------------- */ #endregion using System; using System.Collections; using System.Globalization; using System.IO; namespace Dotnet.Commons.IO { /// /// <summary> /// This class provides basic facilities for manipulating files and file paths. /// /// <h3>File-related methods</h3> /// There are methods to /// <list type="bullet"> /// <item>copy a file to another file,</item> /// <item>compare the content of 2 files,</item> /// <item>delete files using the wildcard character,</item> /// <item>etc</item> /// </list> /// </summary> /// public sealed class FileUtils { /// --------------------------------------------------------------- /// <summary> /// Implements the same behaviour as the "touch" utility on Unix. It creates /// a new file with size 0 or, if the file exists already, it is opened and /// closed without modifying it, but updating the file date and time. /// </summary> /// <param name="file"> File to touch</param> /// <exception cref="IOException">If an I/O problem occurs</exception> /// --------------------------------------------------------------- public static void Touch(FileInfo file) { if (file.Exists) { FileStream fs = file.OpenRead(); fs.Close(); file.LastAccessTime = DateTime.Now; file.Refresh(); } else { FileStream fs = file.OpenWrite(); fs.WriteByte(0); fs.Close(); file.Refresh(); } } } }
Clean a directory without deleting it
#region License and Copyright
/* ————————————————————————-
* Dotnet Commons IO
*
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the
*
* Free Software Foundation, Inc.,
* 59 Temple Place,
* Suite 330,
* Boston,
* MA 02111-1307
* USA
*
* ————————————————————————-
*/
#endregion
using System;
using System.Collections;
using System.Globalization;
using System.IO;
namespace Dotnet.Commons.IO
{
class MainClass{
/// ————————————————————————–
///
/// directory path to clean
///
/// ————————————————————————–
public static void CleanDirectory(string path)
{
bool tmpBool;
if (File.Exists(path))
tmpBool = true;
else
tmpBool = Directory.Exists(path);
if (!tmpBool)
throw new ArgumentException(path + ” does not exist”);
if (!Directory.Exists(path))
throw new ArgumentException(path + ” is not a directory”);
IOException exception = null;
DirectoryInfo dir = new DirectoryInfo(path);
FileInfo[] files = dir.GetFiles();
foreach(FileInfo f in files)
{
try
{
f.Delete();
}
catch (IOException ioe)
{
exception = ioe;
}
}
DirectoryInfo[] subdirs = dir.GetDirectories();
for (int i = 0; i < subdirs.Length; i++)
{
try
{
subdirs[i].Delete(true);
}
catch (IOException ioe)
{
exception = ioe;
}
}
if (null != exception)
{
throw exception;
}
}
}
}
[/csharp]
Copy file from source to destination
#region License and Copyright /* ------------------------------------------------------------------------- * Dotnet Commons IO * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the * * Free Software Foundation, Inc., * 59 Temple Place, * Suite 330, * Boston, * MA 02111-1307 * USA * * ------------------------------------------------------------------------- */ #endregion using System; using System.Collections; using System.Globalization; using System.IO; namespace Dotnet.Commons.IO { class MainClass{ /// -------------------------------------------------------------------------- /// <summary> /// Copy file from source to destination. The directories up to /// <i>destination</i> will be created if they don't already exist. /// </summary> /// <param name="source"></param> /// <param name="destination"></param> /// -------------------------------------------------------------------------- public static void CopyFile(string source, string destination) { FileInfo sourceFile = new FileInfo(source); FileInfo destFile = new FileInfo(destination); CopyFile(sourceFile, destFile); } /// -------------------------------------------------------------------------- /// <summary> /// Copy file from source to destination. The directories up to /// <i>destination</i> will be created if they don't already exist. /// <i>destination</i> will be overwritten if it already exists. /// The copy will have the same file date as the original. /// </summary> /// <param name="source">An existing non-directory <see cref="FileInfo"/> to copy</param> /// <param name="destination">A non-directory <see cref="FileInfo"/> to write bytes to</param> /// <exception cref="IOException"/> /// <exception cref="FileNotFoundException"/> /// <remarks>Ported from Jakarta Commons IO FileUtils</remarks> /// -------------------------------------------------------------------------- public static void CopyFile(FileInfo source, FileInfo destination) { CopyFile(source, destination, true, true); } /// -------------------------------------------------------------------------- /// <summary> /// Copy file from source to destination. The directories up to /// <i>destination</i> will be created if they don't already exist. /// </summary> /// <param name="source">An existing non-directory <see cref="FileInfo"/> to copy</param> /// <param name="destination">A non-directory <see cref="FileInfo"/> to write bytes to</param> /// <param name="preserveFileDate">flag to indicate if the file date of /// the copy should be the same as the original.</param> /// <param name="overwriteIfExists">Flag to indicate if the file /// is to be overwritten if already exists</param> /// <exception cref="IOException"/> /// <exception cref="FileNotFoundException"/> /// <remarks>Ported from Jakarta Commons IO FileUtils</remarks> /// -------------------------------------------------------------------------- public static void CopyFile(FileInfo source, FileInfo destination, bool preserveFileDate, bool overwriteIfExists) { //check source exists if (!source.Exists) { string message = "File '" + source.FullName + "' does not exist"; throw new FileNotFoundException(message); } //does destinations directory exist ? if (destination.Directory != null && !destination.Directory.Exists) { destination.Directory.Create(); } //make sure we can write to destination if (destination.Exists && (destination.Attributes & FileAttributes.ReadOnly)== FileAttributes.ReadOnly) { String message = "Unable to open file '" + destination.FullName + "' for writing."; throw new IOException(message); } //makes sure it is not the same file if (source.DirectoryName.Equals(destination.DirectoryName)) { String message = "Unable to write file '" + source + "' on itself."; throw new IOException(message); } File.Copy(source.FullName, destination.FullName, overwriteIfExists); destination.Refresh(); if (source.Length != destination.Length) { String message = "Failed to copy full contents from " + source.FullName + " to " + destination.FullName; throw new IOException(message); } if (preserveFileDate) { //file copy should preserve file date destination.LastWriteTime = source.LastWriteTime; } } /// <summary> /// Copy all the files in a directory into a destination folder. This operation performs /// a deep copy, meaning it copies all the files in the subdirectory inside the source directory. /// </summary> /// <param name="sourcePath">source directory to copy from</param> /// <param name="destinationPath">destination to copy to</param> /// <exception cref="ArgumentException">If the source directory does not exist</exception> /// <exception cref="IOException">if an I/O error occurs while copying the files</exception> public static void CopyFiles(string sourcePath, string destinationPath) { CopyFiles(new DirectoryInfo(sourcePath), new DirectoryInfo(destinationPath)); } /// <summary> /// Copy all the files in a directory into a destination folder. This operation performs /// a deep copy, meaning it copies all the files in the subdirectory inside the source directory. /// </summary> /// <param name="source">source directory to copy from</param> /// <param name="destination">destination to copy to</param> /// <exception cref="ArgumentException">If the source directory does not exist</exception> /// <exception cref="IOException">if an I/O error occurs while copying the files</exception> public static void CopyFiles(DirectoryInfo source, DirectoryInfo destination) { if (!source.Exists) throw new ArgumentException(string.Format("Source directory '{0}' does not exist", source)); if (!destination.Exists) destination.Create(); FileInfo[] sourceFiles = source.GetFiles(); foreach (FileInfo file in sourceFiles) { file.CopyTo(destination.FullName + Path.DirectorySeparatorChar + file.Name); } DirectoryInfo[] subdirs = source.GetDirectories(); foreach (DirectoryInfo subdir in subdirs) { DirectoryInfo destSubDir = Directory.CreateDirectory(destination.FullName + Path.DirectorySeparatorChar + subdir.Name); CopyFiles(subdir, destSubDir); } } } }
Compares the content of 2 files
#region License and Copyright /* ------------------------------------------------------------------------- * Dotnet Commons IO * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the * * Free Software Foundation, Inc., * 59 Temple Place, * Suite 330, * Boston, * MA 02111-1307 * USA * * ------------------------------------------------------------------------- */ #endregion using System; using System.Collections; using System.Globalization; using System.IO; namespace Dotnet.Commons.IO { class MainClass{ /// --------------------------------------------------------------- /// <summary> /// This method compares the content of 2 files. A return value of true /// indicates that the contents of the files /// are the same. A return value of false indicates that the /// files are not the same. /// </summary> /// <param name="firstFile">first file to be compared against the second</param> /// <param name="secondFile">second file to be compared against the first</param> /// <returns>true if they are the same, false otherwise</returns> /// <remarks> /// This method has been modified to increase the speed in which this /// file comparing operation performs. /// /// The MSDN knowledge base: /// How to create a File-Compare function in Visual C# /// http://support.microsoft.com/default.aspx?scid=kb;en-us;320348 /// was used to assist in speeding up this operation. /// </remarks> /// --------------------------------------------------------------- public static bool Compare(FileInfo firstFile, FileInfo secondFile) { if (!firstFile.Exists) { string message = "File '" + firstFile.FullName + "' does not exist"; throw new FileNotFoundException(message); } if (!secondFile.Exists) { string message = "File '" + secondFile.FullName + "' does not exist"; throw new FileNotFoundException(message); } // Check Each byte FileStream fs1 = new FileStream(firstFile.FullName, FileMode.Open, FileAccess.Read); FileStream fs2 = new FileStream(secondFile.FullName, FileMode.Open, FileAccess.Read); // Check the file sizes. If they are not the same, the files // are not the same. if (fs1.Length != fs2.Length) { // Close the file fs1.Close(); fs2.Close(); // Return false to indicate files are different return false; } int file1byte; int file2byte; // Read and compare a byte from each file until either a // non-matching set of bytes is found or until the end of // file1 is reached. do { // Read one byte from each file. file1byte = fs1.ReadByte(); file2byte = fs2.ReadByte(); } while ((file1byte == file2byte) && (file1byte != -1)); // Close the files. fs1.Close(); fs2.Close(); // Return the success of the comparison. "file1byte" is // equal to "file2byte" at this point only if the files are // the same. return ((file1byte - file2byte) == 0); } /// <summary> /// Compare the contents two files. /// </summary> /// <param name="firstFile">first file to be compared against the second</param> /// <param name="secondFile">second file to be compared against the first</param> /// <returns>true if they are the same, false otherwise</returns> public static bool Compare(string firstFile, string secondFile) { FileInfo fiFirstFile = new FileInfo(firstFile); FileInfo fiSecondFile = new FileInfo(secondFile); return Compare(fiFirstFile, fiSecondFile); } } }
Returns a human-readable version of the file size (original is in bytes).
#region License and Copyright /* ------------------------------------------------------------------------- * Dotnet Commons IO * * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the * * Free Software Foundation, Inc., * 59 Temple Place, * Suite 330, * Boston, * MA 02111-1307 * USA * * ------------------------------------------------------------------------- */ #endregion using System; using System.Collections; using System.Globalization; using System.IO; namespace Dotnet.Commons.IO { class MainClass{ /// <summary>The number of bytes in a kilobyte.</summary> public const long ONE_KB = 1024; /// <summary>The number of bytes in a megabyte.</summary> public const long ONE_MB = ONE_KB * ONE_KB; /// <summary> The number of bytes in a gigabyte.</summary> public const long ONE_GB = ONE_KB * ONE_MB; /// -------------------------------------------------------------------------- /// <summary> /// Returns a human-readable version of the file size (original is in bytes). /// </summary> /// <param name="size">The number of bytes.</param> /// <returns>A human-readable display value (includes units).</returns> /// -------------------------------------------------------------------------- public static string DisplaySize(long size) { string displaySize; if (size / ONE_GB > 0) { displaySize = Convert.ToString(size / ONE_GB) + " GB"; } else if (size / ONE_MB > 0) { displaySize = Convert.ToString(size / ONE_MB) + " MB"; } else if (size / ONE_KB > 0) { displaySize = Convert.ToString(size / ONE_KB) + " KB"; } else { displaySize = Convert.ToString(size) + " bytes"; } return displaySize; } } }
Uses StreamReader and StreamWriter object using different encoding to translate a file from one to another
/* C# Programming Tips & Techniques by Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794 */ // StrmCnvt.cs -- Uses StreamReader and StreamWriter object using different // encoding to translate a file from one to another // // Compile this program with the following command line: // C:>csc StrmCnvt.cs using System; using System.IO; using System.Text; namespace nsStreams { public class StrmCnvt { static public void Main () { FileStream istrm; FileStream ostrm; StreamReader reader; StreamWriter writer; try { // Open the input file istrm = new FileStream ("./StrmRdr.txt", FileMode.Open, FileAccess.Read); // Link a stream reader to the stream reader = new StreamReader (istrm, Encoding.ASCII); } catch (Exception e) { Console.WriteLine (e.Message); Console.WriteLine ("Cannot open ./StrmRdr.txt"); return; } try { // Open the output file ostrm = new FileStream ("./StrmRdr.Uni", FileMode.OpenOrCreate, FileAccess.Write); // Link a stream reader to the stream writer = new StreamWriter (ostrm, Encoding.Unicode); } catch (Exception e) { Console.WriteLine (e.Message); Console.WriteLine ("Cannot open ./StrmRdr.Uni"); return; } ostrm.SetLength (0); while (reader.Peek () >= 0) { string str = reader.ReadLine (); writer.WriteLine (str); } reader.Close (); istrm.Close (); writer.Close (); ostrm.Close (); } } } //File: StrmRdr.txt /* I Hear America Singing I hear American Mouth-Songs, the varied carols I hear; Those of mechanics -- each one singing his, as it should be, blithe and strong; The carpenter singing his, as he measures his plank or beam, The mason singing his, as he makes ready for work, or leaves off work; The boatman singing what belongs to him in his boat -- the deckhand singing on the steamboat deck; The shoemaker singing as he sits on his bench -- the hatter singing as he stands; The wood-cutter's song -- the ploughboy's, on his way in the morning, or at the noon intermission, or at sundown; The delicious singing of the mother -- or of the young wife at work -- or of the girl sewing or washing -- Each singing what belongs to her, and to none else; The day what belongs to the day -- At night, the party of young fellows, robust, friendly; Singing, with open mouths, their strong melodious songs. -- Walt Whitman, 1860 */
Read/Write File Transacted
/*== == Copyright : BlueCurve (c) == Licence : Gnu/GPL v2.x == Author : Teddy Albina == Email : bluecurveteam@gmail.com == Web site : http://www.codeplex.com/BlueCurve */ using System; using System.IO; using System.Text; using System.Transactions; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; namespace BlueCurve.Search.Common.IO { /// <summary> /// Fournit des méthodes de gestions du système de fichier /// </summary> public class CommonStream { #region Import native methods /// <summary> /// Méthode native vérifiant si un répertoire est vide /// </summary> /// <param name="pszPath">Chemin du répertoire à tester</param> /// <returns>bool</returns> [DllImport("shlwapi.dll", CharSet = CharSet.Auto)] private extern static bool PathIsDirectoryEmpty(string pszPath); #region 'Kernel transaction manager api management' /// <summary> /// Represente un handle de transaction /// </summary> public sealed class SafeTransactionHandle : SafeHandleZeroOrMinusOneIsInvalid { private SafeTransactionHandle() : base(true) { } public SafeTransactionHandle(IntPtr preexistingHandle, bool ownsHandle) : base(ownsHandle) { SetHandle(preexistingHandle); } public enum FileAccess { GENERIC_READ = unchecked((int)0x80000000), GENERIC_WRITE = 0x40000000 } [Flags] public enum FileShare { FILE_SHARE_NONE = 0x00, FILE_SHARE_READ = 0x01, FILE_SHARE_WRITE = 0x02, FILE_SHARE_DELETE = 0x04 } public enum FileMode { CREATE_NEW = 1, CREATE_ALWAYS = 2, OPEN_EXISTING = 3, OPEN_ALWAYS = 4, TRUNCATE_EXISTING = 5 } [DllImport("Kernel32.dll", SetLastError = true)] private static extern bool CloseHandle(IntPtr handle); override protected bool ReleaseHandle() { return CloseHandle(handle); } } /// <summary> /// Importation de la fonction native CreateFileTransacted() permettant /// de créer une transaction ntfs /// </summary> /// <returns>SafeFileHandle</returns> [DllImport("Kernel32.Dll", EntryPoint = "CreateFileTransacted", CharSet = CharSet.Unicode, SetLastError = true)] protected static extern SafeFileHandle CreateFileTransacted( [In] String lpFileName, [In] SafeTransactionHandle.FileAccess dwDesiredAccess, [In] SafeTransactionHandle.FileShare dwShareMode, [In] IntPtr lpSecurityAttributes, [In] SafeTransactionHandle.FileMode dwCreationDisposition, [In] int dwFlagsAndAttributes, [In] IntPtr hTemplateFile, [In] SafeTransactionHandle txHandle, [In] IntPtr miniVersion, [In] IntPtr extendedOpenInformation ); /// <summary> /// Importation de l'interface KTM /// </summary> [ComImport] [Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] protected interface IKernelTransaction { void GetHandle(out SafeTransactionHandle ktmHandle); } #endregion #endregion /// <summary> /// Copie un stream dans un autre /// de façon asynchrone /// http://msdn.microsoft.com/fr-fr/magazine/cc337900.aspx /// </summary> /// <param name="source">Stream source</param> /// <param name="destination">Stream destination</param> /// <param name="completed">Action()</param> public static void CopyStreamToStream(FileStream source, FileStream destination, Action<FileStream, FileStream, Exception> completed) { byte[] buffer = new byte[0x1024]; System.ComponentModel.AsyncOperation asyncOp = System.ComponentModel.AsyncOperationManager.CreateOperation(null); Action<Exception> done = e => { if (completed != null) asyncOp.Post(delegate { completed(source, destination, e); }, null); }; AsyncCallback rc = null; rc = readResult => { try { int read = source.EndRead(readResult); if (read > 0) { destination.BeginWrite(buffer, 0, read, writeResult => { try { destination.EndWrite(writeResult); source.BeginRead( buffer, 0, buffer.Length, rc, null); } catch (Exception exc) { done(exc); } }, null); } else done(null); } catch (Exception exc) { done(exc); } }; source.BeginRead(buffer, 0, buffer.Length, rc, null); } /// <summary> /// Vérifie qu'un répertoire est vide /// </summary> /// <param name="path">Chemin de fichier du répertoire</param> /// <returns>bool</returns> public static bool DirectoryIsEmpty(string path) { return PathIsDirectoryEmpty(path); } #region Transactional methods /// <summary> /// Ecrit un fichier de façon transactionnel /// </summary> /// <param name="data">Données à écrire</param> /// <param name="path">Chemin du fichier dans lequel écrire les données</param> /// <returns>Statut de l'opération</returns> public static bool WriteFileTransacted(object data, string path) { if (data == null) return false; SafeTransactionHandle txHandle = null; SafeFileHandle fileHandle = null; bool response = true; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(System.Transactions.Transaction.Current); kernelTx.GetHandle(out txHandle); fileHandle = CreateFileTransacted( path , SafeTransactionHandle.FileAccess.GENERIC_WRITE , SafeTransactionHandle.FileShare.FILE_SHARE_NONE , IntPtr.Zero , SafeTransactionHandle.FileMode.CREATE_ALWAYS , 0 , IntPtr.Zero , txHandle , IntPtr.Zero , IntPtr.Zero); if (fileHandle.IsInvalid) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); using (FileStream stream = new FileStream(fileHandle, FileAccess.Write, 1024, false)) { BinaryFormatter writer = new BinaryFormatter(); writer.Serialize(stream, data); stream.Close(); } } catch { System.Transactions.Transaction.Current.Rollback(); response = false; } finally { if (fileHandle != null && !fileHandle.IsInvalid) { fileHandle.Close(); fileHandle.Dispose(); } if (txHandle != null && !txHandle.IsInvalid) { txHandle.Close(); txHandle.Dispose(); } } return response; } /// <summary> /// Lit un fichier de façon transactionnel /// </summary> /// <param name="path">Chemin du fichier à lire</param> /// <returns>Données lu</returns> public object ReadFileTransacted(string path) { if (!File.Exists(path)) return null; SafeTransactionHandle txHandle = null; SafeFileHandle fileHandle = null; object raw = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(System.Transactions.Transaction.Current); kernelTx.GetHandle(out txHandle); fileHandle = CreateFileTransacted( path , SafeTransactionHandle.FileAccess.GENERIC_READ , SafeTransactionHandle.FileShare.FILE_SHARE_READ , IntPtr.Zero , SafeTransactionHandle.FileMode.OPEN_ALWAYS , 0 , IntPtr.Zero , txHandle , IntPtr.Zero , IntPtr.Zero); if (fileHandle.IsInvalid) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); using (FileStream stream = new FileStream(fileHandle, FileAccess.Read, 1024, false)) { BinaryFormatter reader = new BinaryFormatter(); raw = reader.Deserialize(stream); } } catch { raw = null; } finally { if (fileHandle != null && !fileHandle.IsInvalid) { fileHandle.Close(); fileHandle.Dispose(); } if (txHandle != null && !txHandle.IsInvalid) { txHandle.Close(); txHandle.Dispose(); } } return raw; } #endregion } }