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

Cachen von Dynamischen Includes

Geschrieben von: Christian Koller
Kategorie: ASP Tricks

This printed page brought to you by AlphaSierraPapa

Wie bereits im Artikel Dynamische Includes in ASP beschrieben, kann unter ASP ab der VBScript Version 5.0 die Execute Methode benutzt werden, um während der Laufzeit (also "dynamisch") Dateien in ASP Seiten zu inkludieren und auszuführen.

Man hat die Möglichkeit, bei jedem Aufruf der ASP Seite die inkludierte Datei von der Festplatte zu lesen. Dies erfordert, daß das FileSystemObject Objekt jedesmal, wenn eine ASP Seite abgearbeitet wird, einen FileStream zur inkludierten Datei öffnet und den Dateiinhalt liest. Der häufige Zugriff auf die Festplatte ist, wie jeder Computeruser aus leidvoller Erfahrung weiß, oftmals der Flaschenhals des Systems. Der Zugriff auf das Netzwerk oder den Speicher erfolgt oft um Zehnerpotenzen schneller.

Daher ist es naheliegend, dynamische Include-Dateien nicht bei jedem Aufruf einer ASP-Seite neu von der Festplatte zu lesen, sondern den Inhalt im Speicher zu behalten, um ihn von dort jederzeit schnell lesen zu können.

Zur Auffrischung noch kurz die Grundlagen darüber, wie ASP Seiten auf einen gemeinsamen Speicher mittels Application Objekt zugreifen können.

Globaler Speicherzugriff unter ASP

ASP bietet zum Verwalten von Speicherinhalten das Application Objekt an. Auf das Application Objekt können alle ASP Dateien der Website zugreifen, sowohl um Werte in Application Variablen zu speichern, als auch um Werte aus Application Variablen auszulesen. Um zu verdeutlichen, wie man das Application Objekt benutzt sehen Sie die folgenden Beispiele.

Um einen Wert in einer Application Variablen zu speichern, benutzt man den folgenden Syntax:

Application("Variablenname") = Variablenwert

Um zu verhindern, daß eine weitere ASP Seite im selben Moment ebenfalls einen Wert in die Application Variable schreibt, kann man die Lock und UnLock Methoden des Application Objektes benutzen:

Application.Lock
Application("Variablenname") = Variablenwert
Application.UnLock

Das Auslesen eines Application Variablenwertes erfolgt analog:

Variablenwert = Application("Variablenname")

Mechanismus des Datei-Cachings

Die Grundanforderungen an das Cachen von dynamisch inkludierten Dateien sind:

Laden des Datei Inhaltes

Das Laden des Datei Inhaltes in den Speicher erfolgt durch das Lesen des Datei Inhaltes mittels FileSystemObject Objekt und dem Speichern in einer Application Variablen. Um sicherzustellen, daß jede Datei in einer eindeutigen Application Variablen gespeichert wird, benutzt man am besten den vollständigen physikalischen Pfad der Datei als Teil des Variablen Namens.

Um den Inhalt einer beliebige Datei in einer Application Variablen abzuspeichern, benutzt man eine Sub wie die folgende:

Sub LoadFileInApplication(strDateiName)
   ' strDateiname in der Form "C:\Testdateien\MeineDatei.txt"
   Dim strDateiInhalt
   strDateiInhalt = ReadFile(strDateiName)
   Application("CachedFile_" & strDateiName) = strDateiInhalt
End Sub

Die Funktion ReadFile liest dabei einfach den Inhalt einer Datei aus, ihr Sourcecode ist im Artikel Dynamische Includes in ASP beschrieben.

Effizenter Zugriff auf Dateien im Cache

Da man den Inhalt einer gecachten Datei einfach aus der zugehörigen Application Variable (und damit dem ihr von Webserver zugeordneten Speicherbereich) lesen kann, ist die Schnelligkeit des Zugriffs gewährleistet. Das Auslesen erfolgt durch Zugriff auf die jeweilige Application Variable:

Function ReadCachedFile(strDateiName)
   ' strDateiName in der Form D:\Webs\aspexpert\www\calc.asp
   ReadCachedFile = Application("CachedFile_" & strDateiName)
End Function

Aktuellste Version der inkludierten Datei bereitstellen

Um zu gewährleisten, daß immer die aktuelleste Version der inkludierten Datei bereitgestellt wird, speichert man das Datum der letzen Modifikation der Datei in einer weiteren Application Variablen, und vergleicht bei einem Zugriff auf die gecachete Datei das Datum der letzten Modifikation der in der Application Variablen gespeicherten Datei mit dem Datum der auf der Festplatte gespeicherten Datei.

Dies erfordert natürlich, daß beim Laden der Datei das dementprechende Datum in einer Application Variablen gespeichert wird.

Genau dieses bewirken die folgenden Funktionen:

Sub LoadFileInApplication(strDateiName)
   ' strDateiname in der Form "C:\Testdateien\MeineDatei.txt"
   Dim strDateiInhalt
   strDateiInhalt = ReadFile(strDateiName)
   Application.Lock
   Application("CachedFile_" & strDateiName) = strDateiInhalt
   ' Datum der letzten Dateiaenderung speichern:
   ' LMD = LastModifiedDate
   Application("CachedFileLMD_" & strDateiName) = DateLastModified(strDateiName)
   Application.UnLock
End Sub

Function DateLastModified(strDateiName)
   Dim objFS, objFile
   DateLastModified = Date()
   Set objFS = CreateObject("Scripting.FileSystemObject")
   On Error Resume Next
   Set objFile = objFS.GetFile(strDateiName)
   DateLastModified = objFile.DateLastModified
   Set objFile = Nothing
   On Error Goto 0
   Set objFS = Nothing
End Function

Um zu sehen, ob die gecachete Datei noch aktuell ist, vergleicht man das "Last Modified Date" der Datei auf der Festplatte mit dem in der Application Variablen gespeichertem Datum, wie im folgenden Script gezeigt:

' Funktion die das "Last Modified Date" der 
' gecachten Datei zurueckgibt:
Function LMDCachedFile(strDateiName)
   ' strDateiName in der Form D:\Webs\aspexpert\www\calc.asp
   LMDCachedFile = Application("CachedFileLMD_" & strDateiName)
End Function

If DateLastModified(strDateiName) > LMDCachedFile(strDateiName) Then
   ' Gecachte Datei ist nicht mehr aktuell
   ... 
End If

Man kann nun die Funktion ReadCachedFile (die zum Auslesen der gecachten Datei aus der Application Variablen dient) so modifizieren, daß Sie prüft, ob die gecachte Version der Datei noch aktuell ist. Ist die Datei auf der Festplatte aktueller als die gecachte, dann wird die Datei von der Festplatte gelesen und gecachte (in der Application Variablen gespeichert). Das neuerliche Lesen und Cachen geschieht durch den Aufruf der Funktion LoadFileInApplication:

Function ReadCachedFile(strDateiName)
   Dim intI, strDateiInhalt
   ' strDateiName in der Form D:\Webs\aspexpert\www\calc.asp
   intI = 0
   While (DateLastModified(strDateiName) > _
         LMDCachedFile(strDateiName)) And (intI < 3)
      ' Gecachte Datei aktualisieren
      LoadFileInApplication(strDateiName)
      intI = intI + 1
   Wend
   ReadCachedFile = Application("CachedFile_" & strDateiName)
End Function

Um auch noch den Festplatten Zugriff für das Lesen des "Letzen Änderungsdatums" der Datei zu minimieren kann man auf eine Technik zurückgreifen, die bei HTML und ASP Seiten schon seit langem bekannt ist: Das Benutzen eines "Gütligkeitsdatums" (Expiration Date) oder einer "Gültigkeitszeitdauer" (Expiration). Dazu spezifiziert man ein Zeitintervall, nachdem frühestens wieder geprüft wird, ob die gecachte Datei noch aktuell ist. Dieses Zeitintervall orientiert sich daran, wie oft eine Datei geändert wird, und wie schnell eine Dateiänderung in den Cache übernommen werden soll.

Wir erweitern also die Funktionen LoadFileInApplication und ReadCachedFile, sodaß ein "Gültigkeitszeitraum" angegeben werden kann, während dem nicht geprüft wird, ob die Datei auf der Festplatte geändert wurde. Neben der Application Variable, die den "Gültigkeitszeitraum" speichert, muß zusätzlich eine weitere Variable mitgeführt werden, die den Zeitpunkt des letzen Auslesen des "Last Modifed Date" der Datei auf der Festplatte festhält.

Sub LoadFileInApplication(strDateiName,ExpireInMinutes)
   ' strDateiname in der Form "C:\Testdateien\MeineDatei.txt"
   ' ExpireInMinutes gibt die Gueltigkeitszeitdauer in Minuten an
   '   nur ganze Zahlen groesser gleich 1 erlaubt
   Dim strDateiInhalt
   strDateiInhalt = ReadFile(strDateiName)
   Application.Lock
   Application("CachedFile_" & strDateiName) = strDateiInhalt
   ' Datum der letzten Dateiaenderung speichern:
   ' LMD = Last Modified Date
   Application("CachedFileLMD_" & strDateiName) = DateLastModified(strDateiName)

   ' Gueltigkeitszeitraum speichern
   ' EXPIM = EXPire In Minutes
   If ExpireInMinutes < 1 Then 
      ExpireInMinutes = 1
   End If
   Application("CachedFileEXPIM_" & strDateiName) = ExpireInMinutes
   ' Zeitpunkt des letzen Auslesens des "Last Modified Date"
   ' der Datei von der Festplatte speichern
   ' LRL = Last Read Last modified date
   Application("CachedFileLRL_" & strDateiName) = Now
   
   Application.UnLock
End Sub

Function ReadCachedFile(strDateiName,ExpireInMinutes)
   Dim intI, strDateiInhalt
   Dim LRL, EXPIM
   ' strDateiName in der Form D:\Webs\aspexpert\www\calc.asp
   LRL = Application("CachedFileLRL_" & strDateiName)
   EXPIM = Application("CachedFileEXPIM_" & strDateiName)
   ' "n" steht fuer Minuten ("m" fuer Monate)
   If DateAdd("n", EXPIM, LRL) < Now Then
      ' Ueberpruefen, ob Datei noch aktuell
      If (DateLastModified(strDateiName) > _
            LMDCachedFile(strDateiName)) Then
         intI = 0
         Do 
            ' Gecachte Datei aktualisieren
            LoadFileInApplication strDateiName, EXPIM
            intI = intI + 1
         Loop While((DateLastModified(strDateiName) > _
            LMDCachedFile(strDateiName)) And (intI < 3))
      End If 
      Application("CachedFileLRL_" & strDateiName) = Now
   End If
   ReadCachedFile = Application("CachedFile_" & strDateiName)
End Function

' Last Read Last modified date
Function LRLCachedFile(strDateiName)
   LRLCachedFile = Application("CachedFileLRL_" & strDateiName)
End Function
 
' EXPiration In Minutes
Function EXPIMCachedFile(strDateiName)
   Application("CachedFileEXPIM_" & strDateiName)
End Function

Function DateLastModified(strDateiName)
   Dim objFS, objFile
   DateLastModified = Date()
   Set objFS = CreateObject("Scripting.FileSystemObject")
   On Error Resume Next
   Set objFile = objFS.GetFile(strDateiName)
   DateLastModified = objFile.DateLastModified
   Set objFile = Nothing
   On Error Goto 0
   Set objFS = Nothing
End Function

' Last Modified Date
Function LMDCachedFile(strDateiName)
   ' strDateiName in der Form D:\Webs\aspexpert\www\calc.asp
   LMDCachedFile = Application("CachedFileLMD_" & strDateiName)
End Function

Function ReadFile(strDateiname)
   ' strDateiname in der Form "C:\Testdateien\MeineDatei.txt"
   Const fsForReading = 1
   Dim strInhalt, strInhaltHTML
   Dim objFs           ' FileSystemObject Objekt
   Dim objTextStream   ' Textstream Objekt
   
   Set objFs = CreateObject("Scripting.FileSystemObject")
   
   On Error Resume Next
   Set objTextStream = objFs.OpenTextFile(strDateiname, fsForReading)
   If Err.Number <> 0 Then
      ' Fehler aufgetreten
      strInhalt = ""
   Else
      strInhalt = objTextStream.ReadAll
   End If
   objTextStream.Close
   On Error Goto 0
   Set objTextStream = Nothing
   Set objFs = Nothing
   ReadFile = strInhalt
End Function

Um dieses Script nun zu benutzen muß man nur die Funktion ReadCachedFile(strDateiName, ExpireInMinutes) aufrufen. Der Parameter strDateiName gibt den physikalischen Pfad zur Datei an, z.B: C:\Webroot\www\Inlcudes\Add.asp. Der Parameter ExpireInMinutes gibt die Anzahl der Minuten an, nach der wieder geprüft werden soll, ob sich auf der Festplatte eine aktuellere Version als im Cache befindet.

Will man einen physikalischen Pfad (C:\Webroot\www\Inlcudes\Add.asp) in einen virtuellen Pfad umwandeln, so kann man sich der Server.MapPath Methode bedienen:

VirtuellerPfad = Server.MapPath(PhysikalischerPfad)

Ausführen von gecachten dynamischen Includes

Um nun schlußendlich die gecachten Includes auszuführen, muß man den Inhalt der gecachten Datei nur mittels der Execute Methode ausführen:

...
strDateiname = Server.MapPath("/Includes/Add.asp")
ExpireInMinutes = 15
strDateiInhalt = ReadCachedFile(strDateiName,ExpireInMinutes)
Execute strDateiInhalt
...

Schlußbemerkung

Will man dynmische Includes auf oftmals aufgerufenen ASP-Seiten verwenden, so empfiehlt sich das Cachen von dynmischen Include Dateien wie in diesem Artikel beschrieben. Die hier gezeigten Listings dienen nur als Illustration und sind durchaus noch ausbaufähig.

This printed page brought to you by AlphaSierraPapa

Download des Codes

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

Verwandte Artikel

Dynamische Includes in ASP
http:/www.aspheute.com/artikel/20000706.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.