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.
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")
Die Grundanforderungen an das Cachen von dynamisch inkludierten Dateien sind:
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.
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
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)
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 ...
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
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20000710.zip
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.