Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Ein Touch-Utility in C#

Geschrieben von: Christoph Wille
Kategorie: C#

This printed page brought to you by AlphaSierraPapa

Das Touch Utility war immer eines meiner Lieblingstools, weil man mit ihm das Datum auf einer Anzahl von Dateien vereinheitlichen kann - zB in einem Downloadarchiv oder bevor man eine Applikation ausliefert. Heute werden wir ein einfaches Touch Utility in C# schreiben, das jeder leicht an seine Präferenzen anpassen kann.

Die Aufgabenstellung habe ich bewußt einfach gehalten: alle Dateien in einem bestimmten Unterverzeichnis sollen mit dem aktuellen Datum und Uhrzeit getoucht werden, inklusive Unterverzeichnissen und deren Inhalt (also rekursiv). Daher sieht das Hauptprogramm auch sehr einfach aus:

using System;
using System.IO;
using System.Text;

class MainClass
{
  public static void Main(string[] args)
  {
    string strDir2Touch = Directory.GetCurrentDirectory();
    Touch myTouch = new Touch();
    myTouch.TouchDirectory(strDir2Touch);
    Console.WriteLine(myTouch.Errors);
  }
}

Die gesamte Funktionalität habe ich in die Klasse Touch gekapselt, nur der Aufruf ist im eigentlichen Hauptprogramm zu finden. Wer übrigens mit dem hardcodierten Verzeichnis nicht zufrieden sein sollte: der Parameter args beinhaltet die Kommandozeilenparameter, man kann das Utility also um explizite Pfadangabe, Wildcards und Datumsvorgabe erweitern (nur drei Beispiele).

Bevor wir uns die Funktion TouchDirectory ansehen, werfen wir einen Blick auf die Membervariablen der Klasse Touch, eine Property und den Konstruktor:

class Touch
{
  protected DateTime m_Touch2CurrentTime;
  protected StringBuilder m_strExceptionStack;
  
  public string Errors
  {
    get { return m_strExceptionStack.ToString(); }
  }
  
  public Touch()
  {
    m_Touch2CurrentTime = DateTime.Now;
    m_strExceptionStack = new StringBuilder();
  }

Die Errors Property (zusammen mit m_strExceptionStack) erlaubt es mir, am Ende des Touchvorganges gesammelt die aufgetretenen Fehler zu listen - meist ein Zugriff verweigert, entweder weil die Datei geöffnet ist, oder man nicht genug Rechte hat. Warum gebe ich nicht gleich alle Fehlermeldungen in die Konsole aus? Nun, auf diese Art ist die Klasse auch in Windowsanwendungen leicht einsetzbar.

Zum Konstruktor ist zu sagen, daß er die Dateizeit auf DateTime.Now setzt. Man könnte ohne weiteres einen zweiten definieren, dem man die Zeit explizit mitübergibt und dann auf m_Touch2CurrentTime zuweist.

Nun aber zum Arbeitstier der Klasse, der Funktion TouchDirectory:

  public void TouchDirectory(string strDirectory)
  {
    DirectoryInfo diThis = null;
    diThis = new DirectoryInfo(strDirectory);
    
    DirectoryInfo[] subDirectories = diThis.GetDirectories();

    for (int i=0; i < subDirectories.Length; i++)
      {
        // only the time setting is done in an exception block
        try
        {
          subDirectories[i].CreationTime = m_Touch2CurrentTime;
          subDirectories[i].LastAccessTime = m_Touch2CurrentTime;
          subDirectories[i].LastWriteTime = m_Touch2CurrentTime;
        }
        catch(Exception e)
        {
          m_strExceptionStack.Append(e.GetType());
          m_strExceptionStack.Append(": ");
          m_strExceptionStack.Append(subDirectories[i].FullName);
          m_strExceptionStack.Append("\r\n");
        }
        
        TouchDirectory(subDirectories[i].FullName);
      }

    FileInfo[] theFiles = diThis.GetFiles();

    for (int i=0; i < theFiles.Length; i++)
    {
      try
        {
            theFiles[i].CreationTime = m_Touch2CurrentTime;
            theFiles[i].LastAccessTime = m_Touch2CurrentTime;
            theFiles[i].LastWriteTime  = m_Touch2CurrentTime;   
        }
        catch(Exception e)
        {
            m_strExceptionStack.Append(e.GetType());
            m_strExceptionStack.Append(": ");
            m_strExceptionStack.Append(theFiles[i].FullName);
            m_strExceptionStack.Append("\r\n");
        }
    }
  }

Der Grund für die Länge des Listings ist in der Hauptsache der Exception Handling Code, der sowohl für Dateien (reiner Touchvorgang), als auch für Verzeichnisse (touchen und rekursiv auflisten) notwendig ist. Im Prinzip ist der Code zu Directory Browsing a la .NET ähnlich, wer mehr über System.IO für Verzeichnisauflistung erfahren möchte, sollte sich diesen Artikel durchlesen.

Damit ist unser Touch Utility auch schon fertig - in ein Verzeichnis im Pfad kopieren, in das zu touchende Verzeichnis wechseln, touch.exe aufrufen, und schon haben alle Dateien die aktuelle (idente) Zeit gesetzt.

Schlußbemerkung

Dieser Artikel hat den Grundstein für ein nützliches Kommandozeilenutility gelegt, das über viele Jahre dem Autor (in anderen Implementierungen) gute Dienste erwiesen hat.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20020226.zip

Verwandte Artikel

Dateien umbenennen
http:/www.aspheute.com/artikel/20020409.htm
Dateityp-Ermittlung in Managed C++
http:/www.aspheute.com/artikel/20020201.htm
Directory Browsing a la .NET
http:/www.aspheute.com/artikel/20000804.htm
Exception Handling in C#
http:/www.aspheute.com/artikel/20000724.htm
Online File Management System mit ASP.NET und C# - Teil 1
http:/www.aspheute.com/artikel/20021031.htm
Online File Management System mit ASP.NET und C# - Teil 2
http:/www.aspheute.com/artikel/20021105.htm
Schleifenbefehle in C#
http:/www.aspheute.com/artikel/20000717.htm
Verwendung von Arrays in C#
http:/www.aspheute.com/artikel/20000731.htm
Wochenberechnung mit .NET
http:/www.aspheute.com/artikel/20020905.htm

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.