Friday, September 28, 2007

Sorting Files by Name, Date, FileSize etc (C#)

It is simple to get a list of files in .NET, you simply do:

string folder = "c:\\windows\\";
string[] files = Directory.GetFiles(folder);

This will get all the files in C:\Windows (does not include subdirectories). However, they are sorted by name (A-Z) and there aren't any options in the GetFiles method to return them in any other order. Luckily, the results are returned as an array and they can be sorted with a custom comparer. I have created a FileComparer class that can be used to sort the files (works in both .NET 1.1 and 2.0):

public class FileComparer : IComparer
{
 public enum CompareBy
 {
  Name /* a-z */,
  LastWriteTime /* oldest to newest */,
  CreationTime  /* oldest to newest */,
  LastAccessTime /* oldest to newest */,
  FileSize /* smallest first */
 }
 // default comparison
 int _CompareBy = (int)CompareBy.Name;
 
 public FileComparer()
 {
 }
 
 public FileComparer(CompareBy compareBy)
 {
  _CompareBy = (int)compareBy;
 }
 
 int IComparer.Compare( object x, object y )
 {
  int output = 0;
  FileInfo file1 = new FileInfo(x.ToString());
  FileInfo file2 = new FileInfo(y.ToString());
  switch(_CompareBy)
  {
   case (int)CompareBy.LastWriteTime:
    output = DateTime.Compare(file1.LastWriteTime, file2.LastWriteTime);
    break;
   case (int)CompareBy.CreationTime:
    output = DateTime.Compare(file1.CreationTime, file2.CreationTime);
    break;
   case (int)CompareBy.LastAccessTime:
    output = DateTime.Compare(file1.LastAccessTime, file2.LastAccessTime);
    break;
   case (int)CompareBy.FileSize:
    output = Convert.ToInt32(file1.Length - file2.Length);
    break;
   case (int)CompareBy.Name:
   default:
    output = (new CaseInsensitiveComparer()).Compare( file1.Name, file2.Name );
    break;
  }
  return output;
 }
}

To use it is fairly simple:

string folder = "c:\\windows\\";
string[] files = Directory.GetFiles(folder);
IComparer comp = new FileComparer(FileComparer.CompareBy.FileSize);
Array.Sort(files, comp);
foreach(string file in files)
{
 Console.WriteLine(file);
}

This will output a list of files in the C:\Windows directory, sorted smallest to largest. If you want it the other way round, just call Array.Reverse(files) after the sort.

Tuesday, September 18, 2007

Google Code uses jQuery

Google Code is now another high profile site that uses jQuery. It is used to show Google Code Blog posts, featured projects and Google Tech Talks on the home page. It doesn't use jQuery's AJAX functionality to get the feeds though.

Wednesday, September 12, 2007

Select box manipulation with jQuery - new plugin: selectedValues

A new plugin has been added for getting the values of options selected in a select box. More details and download from the Select Box Manipulation project page at the jQuery site.

Friday, September 07, 2007

CssCompact: A WebHandler for shrinking CSS files (ASP.NET)

Update (20 Feb 2010): Static regular expression, compiled (performance improvement, but will be negligible for low volume sites). See Compacting CSS on-the-fly for an HttpHandler based on this.

Update (08 July 2009): Check file extension is CSS.

CssCompact is a simple WebHandler for sending smaller CSS files to the client. It simply removes linebreaks, tabs, spaces (before CSS properties) and comments. That way you can still have your commented CSS code, and also save bandwidth.

Use is simple, just pass on the stylesheet as a parameter when loading your stylesheet:

Add to <head>:

<link rel="stylesheet" type="text/css" href="/style/CssCompact.ashx?stylesheet=/style/style.css" />

or

<style type="text/css"> @import "/style/CssCompact.ashx?stylesheet=/style/style.css"; </style>

Create CssCompact.ashx:

<%@ WebHandler Language="C#" Class="CssCompact" %>

using System;
using System.Web;
using System.IO;
using System.Text.RegularExpressions;

public class CssCompact : IHttpHandler
{
 // remove linebreaks, whitespace and comments
 private static RemoveRegex = new Regex(@"^\s+|/\*([^*\\\\]|\*(?!/))+\*/|\r|\n|\t", RegexOptions.Multiline | RegexOptions.Compiled);
 public void ProcessRequest(HttpContext c)
 {
  string stylesheet = c.Request.QueryString["stylesheet"];
  c.Response.ContentType = "text/css";
  if (stylesheet != null)
  {
   string filename = c.Server.MapPath(stylesheet);
   FileInfo f = new FileInfo(filename);
   if(f.Extension == ".css" && f.Exists)
   {
    c.Response.AddHeader("Last-Modified", f.LastWriteTime.ToString("U"));
    c.Response.Expires = 0;
    if(c.Request.HttpMethod != "HEAD")
    {
     using (StreamReader cssStream = f.OpenText())
     {
      string cssContent = cssStream.ReadToEnd();
      cssContent = RemoveRegex.Replace(cssContent, "");
      c.Response.Write(cssContent);
      c.Response.End();
     }
    }
   }
  }
  c.Response.Write("/* No valid style sheet selected */");
  c.Response.End();
 }

 public bool IsReusable
 {
  get
  {
   return false;
  }
 }

}