| << 10.4.2- Server-Side Includes | Chapter10 | 10.5.0- The RegExp Object >> |
The Text Stream Object
The TextStream object allows you access the contents of a file as a text file. This does not mean that the file has to have a .txt extension. Rather, its contents have to be in text readable form. Naturally, .txt files work fine. But you can also open .html files, .asp files, and even .log files. Once you have access to the text contents of a file, you can read information from it and write information to it.
There are three ways that you can get a TextStream object. With a valid File object, you can use the OpenAsTextStream method. This will return a TextStream object that you can then use to manipulate the contents of the file. If you know the physical file name of the file, and don't want to worry about creating a File object for it, then the FileSystemObject object's OpenTextFile method will open the file in the same way. Lastly, if you want to create a brand new file and add text to it, you can use the CreateTextFile method of the FileSystemObject object and pass it the name of the file you want to create. This method will return a TextStream object, which you can use to add text to the file.
Try It Out – ASP Source Code Viewer
Our first example will look at just accessing the information contained in a file. One of the best ways to learn how to program on the web is to look at other people's source code. You can learn many HTML tricks by looking at the source code of pages you like. But how can you use this same approach to learn the insides of ASP? With ASP, the source is interpreted on the server, and all the client sees is the completed HTML.
In this example, we will create an Active Server Pages script that will display the source of any of the ASP files on your server. The file name will be passed in as a URL parameter. We will also show how to link it to an existing ASP page.
1. Using your editor of choice, create the DisplaySource.asp file with the following source code:
<%
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim strPathInfo, strPhysicalPath
strPathInfo = Request.QueryString("FileName")
strPhysicalPath = Server.MapPath(strPathInfo)
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.GetFile(strPhysicalPath)
%>
<HTML>
<HEAD>
<TITLE><%= objFile.Name %> Source Code</TITLE>
</HEAD>
<BODY>
Source code for <%= objFile.Name %><HR><P>
<FONT FACE=Courier SIZE=2>
<%
Dim objFileTextStream
Set objFileTextStream = objFile.OpenAsTextStream(ForReading, TristateUseDefault)
Dim strLine
Do While objFileTextStream.AtEndOfStream <> True
strLine = Server.HTMLEncode(objFileTextStream.ReadLine)
strLine = Replace (strLine, Chr(9), " ")
Response.Write strLine
Response.Write "<BR>" + vbCrLf
Loop
objFileTextStream.Close
%>
</FONT>
<BR>
<BR>
<HR>
<A href="<%= strPathInfo %>">Return to Displayed File</A>
</BODY>
</HTML>
2. Save this file in your BegASPFiles folder.
3. To link to this file, add this source code to the InteractiveDirectory.asp file from a previous example:
</TABLE>
<!-- #include file="FileDetails.asp" -->
<HR>
<A href="DisplaySource.asp?FileName=
<%= Server.URLEncode(Request.ServerVariables("PATH_INFO")) %> ">
Click here to see ASP source</A>
</BODY>
</HTML>
4. View the page InteractiveDirectory.asp in your web browser.
|
|
5. When you click on the hyperlink at the bottom of the page, you will then see this in your browser.
|
|
How It Works
For this application to work, we need to build on what we did in the previous examples. In order to create a TextStream object, we need to start with a valid File object for the file we are interested in. To get this, we will use the tried and tested method that we have used in the previous examples.
Dim objFSO, objFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
The difference in this case is that the virtual path to the file we are interested in is passed in as a query string variable. So, to begin our steps to getting a File object, we need to use that passed in value to compute the physical file path, instead of using a server variable as we did in the other examples.
Set objFile = objFSO.GetFile(strPhysicalPath)
Once we have the valid File object, the next step is to open that file as a text file. To do this, we will use the OpenAsTextStream method of the File object. This method will return a reference to a TextStream object that contains the contents of the file.
Dim objFileTextStream
Set objFileTextStream = objFile.OpenAsTextStream(ForReading, TristateUseDefault)
The OpenAsTextStream method takes two parameters:
OpenAsTextStream(ForReading, TristateUseDefault)
The first parameter is used to determine the state the file is opened in. There are three possible states for opening the file. To make the code more readable, we have defined constants at the top of the source file for these three states.
The possible values are:
- ForReading – The file is read-only. You cannot write any information to this file.
- ForWriting – You are able to write to the file. If there is any data that was already in the file, it will be overwritten as soon as you open it in this mode.
- ForAppending – You are able to read the file, as well as add text to the end of it. You cannot change any of the text that was originally there.
The second parameter indicates in what file format the file should be opened. Possible values are:
- TristateTrue – This will open the file in UNICODE format.
- TristateFalse – This will open the file in ASCII format.
- TristateUseDefault – This will use the default setting for the web server.
To be safe, you should usually open the file in the default mode, unless you are absolutely sure that the contents are not of the default type.
Once the file is open, we can begin reading the information from the file. There are a number of ways information can be read from the file. It can be read all at once, using the ReadAll method. This will return all of the text in the file in one big chunk. While this is the easiest to implement, it isn't very effective for large files. Rather than reading the file all at once, it can be read in pieces. There are two different size chunks that can be read from a file. The Read method can be used to read a certain number of characters from the file into a string. This number of characters is determined by a parameter passed to the Read method. Alternatively, the file can be read one line at a time, as we have done in this example - using the ReadLine method:
Dim strLine
Do While objFileTextStream.AtEndOfStream <> True
strLine = Server.HTMLEncode(objFileTextStream.ReadLine)
strLine = Replace (strLine, Chr(9), " ")
Response.Write strLine
Response.Write "<BR>" + vbCrLf
Loop
objFileTextStream.Close
This method will return all of the text starting at the current location in the file up to the first line break. When you have a file open for reading, the TextStream object maintains a pointer in the file indicating where you last read text. When you first open the file, this pointer is pointing at the beginning of the file. When you read text from the file using either the Read or ReadLine methods, the object moves this pointer to a point just after where you finished reading. In the case of the ReadLine method, the pointer will be pointing at the first character after the line break.
As you are reading the file piece by piece, you will need some indication as to when you have run out of file to read. The TextStream object provides a property that is very simple to access, which will tell you when you are at the end of the file. The AtEndOfStream property will return True when you have reached the end of the file.
As we want to read the file one line at a time, we use the ReadLine method. Since we want to read the entire file, we will need to call the ReadLine method over and over again until we have read the entire file. This can be easily done using a loop. The condition that we are checking every time we go through the loop is based on the AtEndOfStream property. As long as this property's value is not true, we still have more data to read, so we can grab the next chunk using the ReadLine method.
Once we have the line stored in a string, there is one more procedure that we need to perform on it. Since we will be displaying primarily the source code for Active Server Pages files, we need to take care of how special characters in the file are handled.
If we were to just spit the contents of the file back to the client using a Response.Write method, we will probably not get the desired results. Since a large part of an ASP source file is HTML, when this is sent back to the client, it will just display it as if it were regular HTML. This will not give us the display that we are interested in.
In order to display the HTML as source, we need to change the way the HTML tags are presented. When the client is displaying an HTML page, it is looking for HTML tags that are bounded by < >. When it finds one of these, it will use it as formatting instructions, and not as text to be displayed. In order for the browser to display the HTML source as text, we need to change the < > to a character that will look the same, but will be interpreted differently.
To do this, we need to look through the string and wherever we find a < or > we need to replace it with a < or > respectively. When the client sees this set of characters, it will display a <, but it will not treat what is inside as an HTML tag. This is exactly what we need for our source code viewer. Lucky for us, there is a very convenient Server object method called HTMLEncode. It does exactly what we need. Given a string, it will search for characters that would be interpreted as HTML by a browser, when we really want it to display as text.
The last bit of formatting that we need to do concerns the area of indented text. Many ASP source files use indented sections to make the code more readable. These indents are usually made using tab characters. Unfortunately, when a web client is told to display a tab character, it will just ignore it. We want our source code display to retain the formatting that the developer added. Again, we will be using the Replace method. This time we will be looking for a tab character. The tab character is one of those non-printable characters. This means that there is no visible character that represents it. But we need a tab character as input to the Replace method. VBScript also provides us with a Chr function. This function will convert a number into its equivalent ASCII character. After consulting our ASCII character chart, we know that the ASCII code for the Tab character is 9. So we will be using Chr(9) as our search sub-string in the Replace method. We will be replacing each of the tab characters with four non-breaking space characters. These are represented as and when the client encounters one of these, it adds an explicit space character to the output.
Now that the whole line is properly formatted, we can output it to the client using the Response.Write method. Since the client will ignore any carriage returns in the text file, we need to add our own line break to the displayed source code. To do this, we add the <BR> tag to the end of the line. Having finished all of the processing on this line, we start our loop all over again with the next line. When we run out of lines to process, we close the TextStream and send the completed page back to the client.
In order to launch this page, we need to add a few lines of code to an existing ASP file. We will be using one of the examples from earlier in this chapter. At the bottom of the page, we will add a hyperlink that will request the DisplaySource.asp file. The name of the file that we are displaying the source for is passed as a URL parameter. Before we pass the file name as a query string variable, we need to make sure that all of the characters in the file name are valid URL characters. The easiest way to do this is to use the Server.URLEncode method. This method will replace any invalid characters in a URL string with their corresponding URL representations. This will ensure that the file name is properly passed to the DisplaySource.asp file, regardless of the characters in the file name. So now, when the user clicks on this link, the source code of the ASP file that generated the page will be displayed for the user.
This example has shown us how to read information from a text file on the server and display it on the client. Next, we will take a look at how to write information to a text file. There are many instances in web applications where you want more detail than is available in the standard server logs, yet you don't want to have a database to write the information to. This example will show how to create an application log file routine that can be packaged into a server-side include and dropped into any ASP file.
Try It Out – Application Log File
In this example, we will be creating a server-side include file that can be added to any of your Active Server Pages script files. This file will provide your script with a method that can be called to write information to a log file. All that your script will need to do is add this include file and then call the method to write the information to the file.
1. Using NotePad, create the WriteLog.asp file with the following source code:
<%
Const ForAppending = 8
Dim strLogFileName
strLogFileName = "c:\AppLogFile.log" 'enter your preferred path here
Dim objLogFileFSO
set objLogFileFSO = CreateObject("Scripting.FileSystemObject")
Dim objLogFileTS
If objLogFileFSO.FileExists(strLogFileName) Then
Set objLogFileTS = objLogFileFSO.OpenTextFile(strLogFileName, ForAppending)
Else
Set objLogFileTS = objLogFileFSO.CreateTextFile(strLogFileName)
End If
Sub WriteToLog (strNewEntry)
Dim strLogEntry
strLogEntry = FormatDateTime(Now) & " - "
strLogEntry = strLogEntry & strNewEntry
objLogFileTS.WriteLine strLogEntry
End Sub
Sub CloseLog()
objLogFileTS.Close
End Sub
%>
2. Save this file in your BegASPFiles folder.
3. Next, add the include statement to your ASP file. For this example, we will be using the DisplayDirectory.asp file that we looked at earlier.
set objFolderContents = objFolder.Files
%>
<!-- #include file="WriteLog.asp" -->
<TABLE cellpadding=5>
4. We'll add another line to DisplayDirectory.asp which will call the WriteToLog method to write information to the log file.
Response.Write objFileItem.DateLastModified
Response.Write "</TD></TR>"
WriteToLog "Directory Entry for " + objFileItem.Name
Next
%>
5. At the end of DisplayDirectory.asp, add a call to the CloseLog method to close the log file.
Response.Write objFileItem.DateLastModified
Response.Write "</TD></TR>"
WriteToLog "Directory Entry for " + objFileItem.Name
Next
CloseLog
%>
6. View the DisplayDirectory.asp file in your web browser. This will cause the server to generate the page, which will write the information to the log file. The contents of the log file, which will be called AppLogFile.log, can be found under the C:\ folder on your web server's hard drive and can be viewed using any editor. In this example, we're using Notepad. The contents will look something like this:
|
|
How It Works
This server-side include file will need to perform two functions. First, it will need to get the TextStream object that represents our log file properly prepared to accept information written to it. Secondly, it will need to provide an easy mechanism for the file that includes it to write information to the log file.
In our example, we have defined the name of the log file. This could have just as easily been stored in a variable and retrieved by the include file. Once we have this file name, which is already a physical file name, we can then prepare the TextStream object to accept information written to it.
Dim objLogFileTS
If objLogFileFSO.FileExists(strLogFileName) Then
Set objLogFileTS = objLogFileFSO.OpenTextFile(strLogFileName, ForAppending)
Else
Set objLogFileTS = objLogFileFSO.CreateTextFile(strLogFileName)
End If
There are two states that we need to work with when preparing the TextStream object. The first state is when there is no log file present. In this case, we need to create the log file and then open it with write permissions enabled. To check to see if the file is present, we will be using the FileExists method of the FileSystemObject object. This method takes the name of a physical file and returns true if the file exists and false if it does not.
If this method returns True, then we know that our log file exists (although it could possibly be empty) and all we need to do is open it. To open it, we will use the OpenTextFile method of the FileSystemObject object. This method will return a TextStream object that represents the file. There are two parameters that we will pass to this method. The first is the name of the physical log file. This is stored in the strLogFileName variable. The second parameter is used to tell the FileSystemObject object what we want to do with this file once we have opened it.
There are two possible values for this parameter. If we just want to read information from the file, then we can set this parameter's value to ForReading. This value will cause the file to be opened as read-only, meaning we can only read information from the file. Since our task here is to create a file that we can write information to, we need to supply the other value for the parameter. The value of ForAppending means that we will be able to both write information to the end of the file. To define the actual value for this parameter, we have included a Const statement to set the value of ForAppending to 8.
If the FileExists method returns False, then we know that we have to create the log file so that we can write to it. This is done using the CreateTextFile method of the FileSystemObject. For this method, we will be supplying one parameter. We will pass in the physical name of the file that we want to create. This method will return a TextStream object that represents our new physical file. This TextStream object will be set up so that information can be written to the file.
The steps involved in opening or creating the file are the first steps in our server side include file. These steps need to be executed as soon as the server reads them from the source file. The other step in the log file is writing information to the log file itself. This needs to be able to be called from anywhere in the source file. In order to do this, we have created a subroutine.
Sub WriteToLog (strNewEntry)
Dim strLogEntry
strLogEntry = FormatDateTime(Now) & " - "
strLogEntry = strLogEntry & strNewEntry
objLogFileTS.WriteLine strLogEntry
End Sub
This subroutine is a feature of the server-side include file. It will accept one parameter and then perform some processing. The parameter will be the text information that is written to the log file. When the method receives this information, it will add a date and time stamp to the beginning of it, then writes the information to the log file. To write the information to the log file, we will be using the WriteLine method of the TextStream object. This method will add the text contained in its one parameter to the file associated with the instance of the TextStream object. It will also add a line break at the end of the text that it adds to the file.
Now that we have created our server-side include file, we need to add the logging functionality to another ASP file. For this example, we will be adding it to the DisplayDirectory.asp file that we looked at earlier in this chapter.
set objFolderContents = objFolder.Files
%>
<!-- #include file="WriteLog.asp" -->
There are three steps to adding the logging capabilities to this file. First, we will need to include the WriteLog.asp file that we just created. This will be done using the #include directive in the DisplayDirectory.asp file. This statement needs to be included prior to any calls to the WriteLog method, so that the method can be properly defined before it is called.
Response.Write objFileItem.DateLastModified
Response.Write "</TD></TR>"
WriteToLog "Directory Entry for " + objFileItem.Name
Next
%>
The next step will be to call the WriteLog method whenever we want to add information to the log file. For this example, we will be writing the name of each file that is read in the current directory to the log file. When you view the log file in Notepad, you can see that the date and time that the entry was made has been added to the beginning of each entry in the log.
Response.Write objFileItem.DateLastModified
Response.Write "</TD></TR>"
WriteToLog "Directory Entry for " + objFileItem.Name
Next
CloseLog
%>
The final step is to call the CloseLog subroutine, which will close the log file on the server.
While logging this type of information may not be very useful on a production basis, because the volume of information being written is just too large, and the problems involved with several sessions trying to write to the same log file at once. There are a number of occasions where a method like this can come in useful. This method can be used to output information to a log file as you are developing a page. If a problem occurs, it is very easy to go back to the log file to see what processing actually took place, and thereby determine what the error was.
| << 10.4.2- Server-Side Includes | Chapter10 | 10.5.0- The RegExp Object >> |

RSS



