Being able to write to text files can give your script a very powerful feature set. Among other things this will enable you to edit many program configurations and system settings, log a script’s output, or create other customized scripts on the fly. Please take the time to read the first article in this series in which I covered how to read text files in WSH.
By far the most common use of writing text files is for logging purposes. We will focus mostly on this application; however, you can easily use the methods provided here for any other purpose that involves writing to a plain text file.
Any time you want to manipulate files in WSH you should automatically think of the FileSystemObject. We’ll begin our script by making a call to its namespace. Familiarize yourself with the FileSystemObject because it is a commonplace in many scripts.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("C:\ScriptLog.txt")
The next step is to create a text file. This is done with the FileSystemObject’s CreateTextFile method. The CreateTextFile method returns an object so we’ll need to use the Set command. To use the CreateTextFile method we must supply it with a file path and name.
That’s the simplest way, but suppose we were doing some more intricate coding. Maybe we’re using dynamic file paths. The following alternative uses a few more methods to create a text file that allows for a little more flexibility and control.
Set objFSO = CreateObject("Scripting.FileSystemObject")
strPath = "C:\path"
strFileName = objFSO.GetTempName
strFile = objFSO.BuildPath(strPath, strFileName)
Set objFile = objFSO.CreateTextFile(strFile)
objFile.Close
objFSO.DeleteFile(strFile)
This code snippet introduces a lot of methods. Let’s take a look at their syntax and then we’ll discuss what the code does.
object.CreateTextFileName[, Overwrite[, Unicode]]
object.BuildPathPath, Filename
object.DeleteFileName[, Force]
Now, let’s go back to our code snippet. We begin by connecting to the FileSystemObject. Next, we assign a path to the strPath string variable. We use the GetTempName method to assign a random name to the strFileName string variable. Now that we have a path and a file name, we use the BuildPath method to combine the two into a full path name which we assign to the strFile string variable. Still with me?
Now we can create the file. We use the CreateTextFile method like we did in our first example. Let’s take a second and talk about its syntax. The only required attribute is a full path to the file that we want created. However, there are a few optional attributes. Overwrite and Unicode are both Boolean attributes that determine whether we should overwrite any existing file (default is True) and whether or not to use Unicode (default is False, meaning to use ASCII) character set, respectively.
Using the Close method to disconnect from a file object will automatically save or discard any changes based on the Iomode used to open it.
After creating the text file, we have to use the Close method to release it before we can delete it with the DeleteFile method. Why close it? The file object is automatically opened for editing when it is created. If we don’t close it first we’re likely to run into some errors when we try to delete it while it’s in use. It’s also good to note that the DeleteFile method has an additional Force attribute that is a Boolean value. The Force attribute allows us to force deletion of Read-only files.
Now let’s take a look at opening an existing text file. The file system object provides the OpenTextFile method. The OpenTextFile method returns a TextStream object so don’t forget to use a Set statement when connecting. The OpenTextFile method uses a simple syntax.
Filename is a full path name to the file we would like to open. Imode takes a Constant value listed in Table 1. Its default is ForReading. Create is a Boolean value. True will create the text file if it doesn’t exist. Its default, False, will generate an error if the file does not exist. Finally, Format is a Tristate constant as listed in Table 2. It defaults to TristateFalse. ASCII is generally acceptable for all purposes. If you’re unsure, just leave it at the default.
Table 1: Constant Values for Iomode Attribute
Constant
Value
Description
ForReading
1
Read-Only
ForWriting
2
Allow writing, overwrite contents
ForAppending
8
Allow writing, append to file rather than overwrite
Table 2: Tristate Values for Format Attribute
Constant
Value
Description
TristateTrue
-1
Unicode
TristateFalse
0
ASCII
TristateUseDefault
-2
Use system default
Be careful using the ForWriting constant as it does overwrite any existing information. If you wish to edit a file: read its contents first, make any changes, and then write it back in its entirety.
We’re going to begin our code by connecting to the FileSystemObject once again. Then we’re going to tell it to connect to our example text file and create it if it doesn’t exist. Let’s take a look at the code.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
objFile.Write("Hello World")
objFile.Close
This simple snippet writes a single line to our text file and then closes the data stream. If you open the C:\ScriptLog.txt file in a text edit such as Notepad you should see the following result.
Hello World
We make use of the TextStream object’s Write method to write a string to our TextStream object. The syntax for the Write object is shown below. Now let’s run our example code again and write a few more strings to our file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
objFile.Write("Hello World")
objFile.Write("This is a test")
objFile.Close
Now if we examine our file we should find that it contains the following text.
Hello WorldThis is a test
As you can see, the Write method simply writes our string to the file pointer’s current position in the file. We never told it to write to a new line so it just appended our second string to the first. There are two ways we can separate this to another line. We’ll look at both in our next example, but first let’s take a look at the syntax for our write methods.
object.Write(string)
object.WriteLine([string])
The write method has a single required parameter and will write the supplied string to a file at the current file pointer position. The WriteLine method will also write to the current file pointer position, but will add a newline character to the end of the supplied string. The string parameter for the WriteLine method is optional and if omitted it will simply write a single newline character.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
objFile.Write("Hello World")
objFile.Write(vbCrLf)
objFile.WriteLine("This is a test")
objFile.Write("This text should be on a new line")
objFile.WriteLine
objFile.WriteLine("As should this")
objFile.Close
Our result should show each string on a new line. We’ve used several different methods in this code to make that happen.
Hello World
This is a test
This text should be on a new line
As should this
ß Note the blank line
The first two Write lines work together. The first wrote our string but left the file pointer on same line. The second Write line was used to manually write a line ending character. In the third line the WriteLine method was used to write a string complete with a linefeed.
Moving on, we used the Write method and the WriteLine method together. The Write method wrote “This text should be on a new line” to our file. Then we used the WriteLine method without any parameters to add a linefeed and move the file pointer to a new line.
Finally, in the last line we used the WriteLine method to write “As should this” to our file. Remember that the WriteLine method always ends with a newline character. That’s why our text file contained a blank line at the end.
You can pretty much solve all of your writing needs with the methods we’ve discussed, but WSH provides us with one more method to make things even easier. It’s nice to be able to space out the text that we write to a text file, but it’s sometimes tedious to do using the Write and WriteLine methods.
object.WriteBlankLines(Int)
The WriteBlankLines methods will write a given number of consecutive newline characters to a file. It accepts a single required parameter, Int, which is an integer indicating how many newline character to write.
Note that the methods provided in this article can only write to TextStream objects. WSH does not provide any way natively to read or edit binary files.
The WriteBlankLines method is used in much the same way as the writing methods we’ve seen previously. Here’s a quick example.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
objFile.WriteLine("This is our first line")
objFile.WriteBlankLines(3)
objFile.Write("This line is written after 3 blank lines")
objFile.Close
Here we’ve used the WriteBlankLines method to write three blank lines in our text file. The output should look like this:
I’m going to quickly present two concepts that you may find very useful when working with text files in your scripts. I’m going to touch on them very briefly so please understand that these are just building blocks to help get you started.
Quite frequently you’ll be using scripts to parse data before writing to a text file. You’ll find that often this means your data will be contained in an array. The following reusable code sample shows how to write text from an array into a comma-delimited text file. You can easily change the delimiter to anything you like. Use the vbTab constant if you want to create a tab-delimited file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
Here we’ve just moved through the array grabbing each name-value pair and joined them with a comma before writing them together as a single line. We could easily have multiple values as well. Just remember to increase your Step value accordingly to avoid processing the same value twice. You could also use this same concept with multi-dimensional arrays.
The final concept I’d like to show you concerns the VBScript Time and Date functions. This time and date stamping is very common in file logging and can be accomplished much more quickly with these functions.
Time()
Date()
The time and Date Functions do not require any parameters and simply return a string containing the local time and date respectively. VBScript provides many different time and date functions if you’re interested in formatting them differently. Here’s a quick example.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("C:\ScriptLog.txt", 2, 1)
objFile.Write(Time() & " " & Date() & " This is a time stamped line")
objFile.Close
This code sample will result in an output similar to the following.
8:07:39 PM 1/21/2007 This is a time stamped line
I hope I’ve provided you with some useful tools that will allow you to add greater functionality to your scripts. You’ll find that being able to read and write text files can be a very useful tool for both logging and debugging. Good luck in your adventures. Until next time, keep coding!