static void

.Net IO

Make ReadOnly/ReadWrite

public static void ToggleFileReadOnly(string path)
 {
       
if (File.Exists(path))
       {
           
FileInfo fileInfo = new FileInfo(path);

           
// is file readonly
           if ((fileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
           
//bitwise XOR - remove the readonly
               fileInfo.Attributes ^= FileAttributes.ReadOnly;
           
else
           //bitwise OR - add the readonly attribute
          fileInfo.Attributes |= FileAttributes.ReadOnly;
       }
   }

Processing CSVs

The Regex way. With a dirty hack for localized Excel csvs (which use semi-colon).

     private static void ProcessFields(string[] fields)
     {
         
//do work with fields here
         throw new Exception("The method or operation is not implemented.");
     }

     
private static void OpenCSVFile(string filename)
     {
         
//,(?=(?:[^"]*"[^"]*")*(?![^"]*"))
         System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
         
char[] trim = { ' ', '"' }; //we'll trim spaces and quotes

         //in vb you could use Microsoft.VisualBasic.FileIO.TextFieldParser
         //for more full-featured reader, see http://www.codeproject.com/cs/database/CsvReader.asp
         using (System.IO.StreamReader sr = new System.IO.StreamReader(filename))
         {
          
bool readHeader = false; //set this to true if no header

          while (sr.Peek() != -1)
          {
              
//bug: in true csv, line breaks within fields are allowed.
              string fileLine = sr.ReadLine();
              
if (fileLine.Length > 0) //ignore blank lines
              {
               
if (!readHeader)
               {
//header line
                if (fileLine.Contains("\";\"")) //tweak this if rqd
                {
                    
//local versions of Excel make csv with semicolons not commas
                    regex = new System.Text.RegularExpressions.Regex(";(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
                }
                readHeader =
true; //discard header
               }
               
else
               {
                
//split the line into fields and trim each field
                string[] fields = regex.Split(fileLine);
                
for (int i = 0; i < fields.Length; i++)
                {
                    fields[i] = fields[i].Trim(trim);
                }
                ProcessFields(fields);
               }
              }
          }
         }
     }

A button_Click to invoke the above.

     private void button1_Click(object sender, EventArgs e)
     {
         openFileDialog1.Title =
"Select CSV file";
         openFileDialog1.Filter =
"Comma Separated Values (*.csv)|*.csv";
         openFileDialog1.DefaultExt =
"csv";
         openFileDialog1.FileName =
"";
         openFileDialog1.InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.Personal);
         
if (openFileDialog1.ShowDialog() == DialogResult.OK)
         {
          OpenCSVFile(openFileDialog1.FileName);
         }
     }

Streams

Writing streams wrap the destination in the ctor and the stream.Write("text") always take the origin. Easy to get it the wrong way round!

Compressing

Create the GZipStream (or DeflateStream, the same without the zip CRC) from the source stream and read-out the bytes into your destination stream. It doesn't cope with .zip files (actually it's unix-like .gz compatible)

private static void CompressFile(string srcPath, string zipPath)
{
    using (FileStream zip = File.Open(zipPath, FileMode.Create)) //destination fs
    {
        using (FileStream src = File.OpenRead(srcPath))//origin fs
        {
            //wrap compression stream around destination stream
            using (GZipStream zipStream = new GZipStream(zip, CompressionMode.Compress))
            {
                //read byte-by-byte from source stream into compression stream
                int eachByte = src.ReadByte();
                while (eachByte != -1)
                {
                    zipStream.WriteByte((byte)eachByte);
                    eachByte = src.ReadByte();
                }
            }
        }
    } //all streams closed
}
private static void DecompressFile(string zipPath, string unzippedPath)
{
    using (FileStream unzipped = File.Open(unzippedPath, FileMode.Create)) //dest fs
    {
        using (FileStream zip = File.OpenRead(zipPath))//origin fs
        {
            //wrap compression stream around zipped stream
            using (GZipStream zipStream = new GZipStream(zip, CompressionMode.Decompress))
            {
                //read byte-by-byte from compression
                int eachByte = zipStream.ReadByte();
                while (eachByte != -1)
                {
                    unzipped.WriteByte((byte)eachByte);
                    eachByte = zipStream.ReadByte();
                }
            }
        }
    } //all streams closed
}

Isolated Storage

WinForms 2.0 Application Settings user.config is not secure...

This gets the My Documents folder (cf ApplicationData)

string PersonalFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

Directory.Copy

There isn't one (just Move), so here's the recursive directory copy

/// <summary>
/// Copies the files in fromPath to the toDirectory. Recursive
/// </summary>
/// <param name="fromPath">From path.</param>
/// <param name="toPath">To path.</param>
public static void CopyFiles(string fromPath, string toPath)
{
    
//directoryInfo.FullName unfortunately doesn't have ending /, so path combines don't work.
    if (!toPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
        toPath +=
Path.DirectorySeparatorChar;
    
DirectoryInfo srcDir = new DirectoryInfo(fromPath);
    
foreach (FileInfo file in srcDir.GetFiles())
    {
        
string newname = Path.Combine(toPath, file.Name); //put the file name onto the root
        file.CopyTo(newname, true);
    }
    
foreach (DirectoryInfo subDir in srcDir.GetDirectories())
    {
        
string subDirName = Path.Combine(toPath, subDir.Name); //put the directory name onto the root
        DirectoryInfo newSubDir = Directory.CreateDirectory(subDirName); //create it
        CopyFiles(subDir.FullName, newSubDir.FullName); //recurse
    }
}

Relative Paths

This creates a windows relative path (../../file.txt). Change two lines (see comments) for a web relative path (..\..\page.html).

/// <summary>
 /// Gets the relative path from one directory to another.
 /// Can take web "/" but always returns windows path.
 /// </summary>
 /// <param name="fromPath">From path.
 /// Should be a directory (a file on the end will be treated as an extra depth of directory)</param>
 /// <param name="toPath">To path. Can be a directory or file path</param>
 /// <returns>Relative path with windows directory separator (\)</returns>
 public string GetRelativePath(string fromPath, string toPath)
 {
    //validate- both must be absolute
    if (fromPath.StartsWith(".")) return toPath;
    if (toPath.StartsWith(".")) return toPath;
 
    //sanitize- web forwardslash changed to windows backslash
    char winSlash = Path.DirectorySeparatorChar;
    char webSlash = Path.AltDirectorySeparatorChar; //swap these around if web paths
    if (fromPath.Contains(webSlash.ToString())) fromPath = fromPath.Replace(webSlash, winSlash);
    if (toPath.Contains(webSlash.ToString())) toPath = toPath.Replace(webSlash, winSlash);
 
    //find what's common
    string[] fromPathFolders = fromPath.Split(winSlash);
    string[] toPathFolders = toPath.Split(winSlash);
    int length = Math.Min(fromPathFolders.Length, toPathFolders.Length);
    int sameUntil = -1;
    for (int i = 0; i < length; i++)
    {
        if (!string.Equals(fromPathFolders[i], toPathFolders[i],
            StringComparison.InvariantCultureIgnoreCase))
            break;
        sameUntil = i;
    }
    if (sameUntil == -1) return toPath; //they are completely different
 
    //walk back up fromPath
    StringBuilder sb = new StringBuilder();
    for (int i = sameUntil + 1; i < fromPathFolders.Length; i++)
    {
        sb.Append(".." + winSlash);
    }
    //walk down the toPath
    for (int i = sameUntil + 1; i < toPathFolders.Length; i++)
    {
        sb.Append(toPathFolders[i]);
        if (i < (toPathFolders.Length - 1)) //not on last one
            sb.Append(winSlash);
    }
    return sb.ToString();
 }

[Test]
public void TestRelativePath()
{
    //web forward slashes converted to windows backslashes
    string fromPath = "root/north";
    string toPath = "root/south/file2.txt"; //to a file
    string expected = @"..\south\file2.txt";
    string actual = GetRelativePath(fromPath, toPath);
    Assert.AreEqual(expected, actual);
 
    fromPath = "root/north";
    toPath = @"root\south"; //to a folder
    expected = @"..\south";
    actual = GetRelativePath(fromPath, toPath);
    Assert.AreEqual(expected, actual);
 
    fromPath = "root/north";
    toPath = @"root\south\"; //slash on end
    expected = @"..\south\"; //is preserved
    actual = GetRelativePath(fromPath, toPath);
    Assert.AreEqual(expected, actual);
 
    fromPath = "mars/north";
    toPath = @"venus\south\"; //not the same root
    expected = toPath; //relative path not applicable
    actual = GetRelativePath(fromPath, toPath);
    Assert.AreEqual(expected, actual);
}

Security

Access rules= DACLs, audit rules= SACL, easy to make an intellisense typo.

private void GetFileOwner(FileInfo f1)
{
    FileSecurity ac = f1.GetAccessControl();
    string name = ac.GetOwner(typeof(NTAccount)).Value; //shows name of owner
    Debug.WriteLine(name);
}
 
private void CopyAccessRulesPreventInheritance(FileInfo f1, FileInfo f2)
{
    const bool protectFromInheriting = true;
    const bool preserveExistingInheritance = true;
    //to copy access rules but prevent inheritance
    FileSecurity acl = f1.GetAccessControl();
    acl.SetAccessRuleProtection(protectFromInheriting, preserveExistingInheritance); //eg true, true so same as old
    f2.SetAccessControl(acl);
}
 
public void TestFileAccessControl()
{
    string initDir = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
    string filePath = Path.Combine(initDir, Guid.NewGuid() + ".tmp");
    File.WriteAllText(filePath, "Temp");
    FileInfo f1 = new FileInfo(filePath);
 
    GetFileOwner(f1);
 
    string filePath2 = @"c:\" + f1.Name;
    f1.CopyTo(filePath2);
    FileInfo f2 = new FileInfo(filePath2);
    CopyAccessRulesPreventInheritance(f1, f2);
 
    f1.Delete();
    f2.Delete();
}