The Wonders of the File System Object

By Chris Payne


NOTE: The computer file system that we'll be manipulating is the web server's. So make sure you have the appropriate privileges and information (i.e., so you don't upset your ISP). Ideally, you'll have a web server set up on your own computer so you can test and play.

FSO Model Objects
Drive Object Provides access to a disk or network drive
FileSystemObject Object Provides access to a computer's file system
Folder Object Provides access to all properties of a folder
TextStream Object Provides an easy way to access a file's contents

You can use the above objects to do nearly anything on a computer, including wreak havoc - so be careful how you play with the FSO. In a web environment, it can be very important to store information, such as user info, log files, etc. The FSO provides a powerful and easy way to store your data in an efficient manner. In this article, we'll be mainly concentrating on the FileSystemObject and TextStream Objects.

NOTE: The FSO is provided by Microsoft, and as such, the results for its use on non-Microsoft operating systems are questionable in the least. For non Windows OSes, you probably wouldn't be using active server pages anyway, but I still wouldn't recommend trying the FSO.

How Do I Use the FSO?

To be able to use the FSO to perform all your dirty work, you must first create the object. If you're familiar with creating objects in ASP pages, then this next line should be no surprise:


Set fso = Server.CreateObject("Scripting.FileSystemObject")


We create the FSO here and set the reference to the variable fso. We can now use the familiar object.method syntax to perform file system manipulations. (Check out the Visual Basic documentation to learn more about objects and object oriented programming.) In this case, we can use fso.method or fso. property, as we'll see in upcoming examples.

NOTE: The FSO model is located in the scripting runtime dll provided by Microsoft, scrrun.dll. You can reference this dll in any application that can reference objects, such as MS Access, Word, and a whole slew of others. This means you're not restricted to just using the FSO in an ASP page.

Here is an abridged list of methods available to the FSO that we will use here to manipulate files:

File Methods
CopyFile Copies one or more files from one place to another
CreateTextFile Creates a file and returns a TextStream object
DeleteFile Deletes a file
OpenTextFile Opens a file and returns a TextStream object that can be used to read from or append to the file

For a complete list of all the methods and properties of the FSO, check out the Microsoft MSDN reference. Let's move onto some examples.

Writing Files

Suppose you wanted to create a simple guestbook. You could set up a database and store users' information there. However, if you don't need the power of a database application, you can save yourself some money and overhead, and use the FSO to store your information. Not to mention the fact that your ISP may limit your choice of database options.

Let's assume you'll collect some user information in a form. Here's the HTML for a simple form:



<form action="formhandler.asp" method="post">

<input type="text" size="10" name="username">

<input type="text" size="10" name="homepage">

<input type="text" size="10" name="Email">




Let's look at the script in formhandler.asp that will handle the form:


' Get form info

strName = Request.Form("username")

strHomePage = Request.Form("homepage")

strEmail = Request.Form("Email")

' create the fso object

Set fso = Server.CreateObject("Scripting.FileSystemObject")

So far, this should be nothing new. We take the form variables and assign them to variables for easier use later on. Now comes the fun part - writing the file:

path = "c:\temp\test.txt"

ForReading = 1, ForWriting = 2, ForAppending = 8

' open the file

set file = fso.opentextfile(path, ForAppending, TRUE)

' write the info to the file

file.write(strName) & vbcrlf

file.write(strHomePage) & vbcrlf

file.write(strEmail) & vbcrlf

' close and clean up


set file = nothing

set fso = nothing

As you recall, the OpenTextFile method returns a TextStream object, which is another object of the FSO model. The TextStream object exposes methods to manipulate a file's content, such as Write, ReadLine, and SkipLine. The VB constant vbcrlf generates a line break.

NOTE: We specify TRUE in the argument list of OpentextFile to tell the system to create the file if it doesn't already exist. If the file does not exist, and you do not specify TRUE, you will generate an ugly error.

Now navigate to c:\temp and open test.txt. You should see the following information:

User's name

User's home page

User's email

Of course those words will be replaced by whatever the user entered in the form. Now anyone can come along and fill out your guestbook and their information will be stored in this file.

Reading Files

So now we have some nice user information stored in a file, which happily works as a simple database. Now suppose a user comes along and wants to view all your wonderful visitors. We've got to spit that information out somehow. Since we don't have a database with nicely structured columns, we'll have to get clever to output the results we want.

We know that in the file we just created, the first line is the user's name, the second line is their homepage, and the third line is their email address. Every subsequent user who comes along will also have their information stored in this way, so that every third line will contain the same type of information. Knowing that, we can now write some code to grab the info:


' create the fso object

set fso = Server.Createobject("Scripting.FileSystemObject")

path = "c:\temp\test.txt"

' open the file

set file = fso.opentextfile(path, 1)  <-- For

Now let's grab each line and format it accordingly:

do until file.AtEndOfStream

        Response.write("Name: " & file.ReadLine & " ")

        Response.write("Home Page: " & file.ReadLine & " ")

        Response.write("Email: " & file.ReadLine & "<p>")


' close and clean up


set file = nothing

set fso = nothing


NOTE: We did a very simple output here, but note that you can place the information wherever and however you like, including in table cells and forms.

If you've created and written your file properly, this little loop will properly list everyone in your database. The ReadLine method reads one line up to the newline character. Subsequent calls to ReadLine will read the next lines. AtEndOfStream is a property of the TextStream object that lets us know when we've hit the end of the file.

Suppose for some reason we didn't format the file correctly. If a user only has 2 lines instead of 3 describing their info, then we will get some errors here. Our loop gets the next 3 lines in the file and if there are not 3 more lines to be had, your page will get mad and throw an error like:

Server object error 'ASP 0177 : 800a003e'

at you. So be sure to add some error checking to make sure you're not skipping or inserting too many lines.


Now that we've covered the basics, we should discuss permissions. The FSO runs in the user account that created it. In other words, if someone accesses your page from the internet, then the internet account created the FSO. If you are logged onto your computer as the administrator and you access the page, then the administrator account created it. This is very important, because certain accounts have certain permissions, and the FSO requires a lot of permissions in order to function fully.

The internet account (IUSER_MachineName, where MachineName is the name of the server) generally has only reading privileges. That means that users will never be able to write to the guestbook file. There are, however, several options to skirt around this issue.

The first, and more difficult, would be to require the user to log on to the server before they fill out the guestbook. However, the point of a guestbook is to get information from anonymous users, and to log users on, we'd have to know who they are, so we'll skip this option and move on.

The second is to create a directory or file that allows the IUSER_MachineName account writing privileges. This can open up some potential security holes, because anyone who knows the proper directory and some savvy web skills can write stuff to your server. This is a big no-no. So you want to make sure you place the writeable directory in a nice and hidden spot, and possibly place it outside of the web directory structure (i.e. in Windows, place it in a directory that is outside the inetpub directory)

Searching with the FSO

You may be thinking "Great, so now I know how to write files. I could've figured that out myself." So you want more tough guy? Let's try building a search feature for your web site.

The key to building a search engine is recursion. If you don't know what recursion is, find out why it's cool. Basically, you write one piece of code that performs a search on the files in a directory, and then make that same code loop through all the subdirectories. Since we don't know ahead of time how many subdirectories there may be, we have to call this piece of code over and over again until we're through. Recursion in it's finest.

So let's build the search page. We'll assume that you've already built an HTML form for a user to input a search string.

Dim objFolder

Dim strSearchText

Dim objFSO

strSearchText = Request.Form("SearchText")  <-- The
search string

' create the FSO and Folder objects

Set fso = Server.CreateObject("Scripting.FileSystemObject")

Set objFolder = objFSO.GetFolder(Server.MapPath("/"))

Search objFolder

The above code simple initializes variables and gets us started. The meat of the search is performed by the Search function, described below:

Function Search(objFolder)

  Dim objSubFolder

  'loop through every file in the current

  For Each objFile in objFolder.Files

    Set objTextStream = objFSO.OpenTextFile(objFile.Path,1) <-- For Reading

        'read the file's contents into a

        strFileContents = objTextStream.ReadAll

        'if the search string is in the file, then
write a link

        ' to the file

        If InStr(1, strFileContents, strSearchText, 1) then

           Response.Write "<A HREF=""/" & objFile.Name & _

                """>" & objFile.Name & "</A><BR>"

           bolFileFound = True

        End If



  'Here's the recursion part - for each

  ' subfolder in this directory, run the Search function again

  For Each objSubFolder in objFolder.SubFolders

        Search objSubFolder


End Function

NOTE: To be able to open files, the FSO requires the actual path to the file, not the web path. For instance, c:\inetpub\wwwroot\temp\index.html, not www.enfused.com/temp/index.html or /temp/index.html. To convert the latter to the former, we use Server.MapPath("filename"), where filename represents the web path.

The code above will run through every subdirectory of every folder under the initial folder that you specified, which in this case, would be the root web path, specified by "/". Then we simply open each file in the directory, see if the desired string is in that file and display a link to that file if the search string is found. Not bad, huh?

Note that as the number of files and subdirectories increases, so will the time it takes to run this search. It's recommended that if you need a heavy duty search feature, turn to something else, such as Microsoft's Index Server.

Content Management with the FSO

By now, you should have a good taste of the FSO and its methods and properties. Let's dig a little deeper and do some engineering design to tackle a more difficult problem.

Content management is being able to keep track of, manipulate, and generally perform tasks with content, typically documents in a web environment. Smart content management does all that in an easy, painless fashion. Behind the scenes of such an application is heavy duty file manipulation. Once again, enter the FSO. We need to be able to move, delete, rename, and create files, and our friend the FSO steps in nicely. In the article above, we discuss a submission system for writers to publish their content. What we don't mention is exactly what to do with the file once it's up.

First of all, you'll most likely want to rename the file, since the writer probably named it something only he would understand or care about. To be able to keep track of all your documents, you'll want to rename it to something unique, that is easily identifiable by your system. Unfortunately, the FSO doesn't allow for an easy file renaming, so we'll have to engineer a bit.


' create the fso object

set fso = Server.Createobject("Scripting.FileSystemObject")

path = "c:\temp\test.txt"

strDate = Replace(Date(), "/", "")

strDir = "c:\inetpub\wwwroot\articles\" & strDate

strNewFileName = Hour(Now) & "_" & Minute(Now) & "_" &

second(Now) & ".html"

' open the old file

set file = fso.opentextfile(path, 1)  <-- For

strText = file.readall

set file = nothing

' check for and/or create folder

if not fso.folderexists(Server.MapPath(strDir)) then

        set f = fso.CreateFolder(Server.MapPath(strDir))


        set f = fso.GetFolder(Server.MapPath(strDir))

end if

' create and write new file

set file = fso.Createtextfile(f.path & "\" & strNewFileName)


set f = nothing


set file = nothing

' delete the old file

fso.DeleteFile(path & "\" & rst("FileName") & i)

' clean up

set fso = nothing


The lack of the FSO's abilities however can be used to our advantage here; we can perform two steps in one. First, we open and read the file's contents. I'll assume that we'll want to create a unique folder, as well as a unique filename to store the article in. However, since this folder's path will change every day, we'll have to first check to see if the folder already exists, and if it doesn't, create it. This is done by the if not fso.folderexists section. We then get that path and use it to create the new file (you'll recall that the FSO needs the full path name to manipulate files, and the GetFolder and CreateFolder methods return just that - a full path). After we're done with the new file, we'll want to get rid of the old one, so it doesn't clutter up our file system. This is accomplished with fso.DeleteFile.

So the two steps we accomplished here were renaming the file, and moving it to a more apropos directory. Note that we could also have done some more manipulation here, such as editing the text before we wrote it to the new file.

What You Can't Do

The FSO does have some weaknesses - for instance, it stumbles on binary files. This includes MS Word documents, many image formats, and, unfortunately, a lot of other files. You can still, however otherwise manipulate these files - move them, delete them, etc. What you can't do is open, read, or write to them. Given some ingenuity, a method could be devised to use the FSO to play with binary files, but many will find it easier to simply use the old Open method.

Another limitation is file size. When you read or write a lot of content at once, all the information is stored in memory - and the larger your content, the larger the memory usage. This tends to slow everything down, so if you need to manipulate really large files, or a ton of smaller files, consider breaking the files down into smaller pieces and clearing the memory often (setting your variables equal to NULL or "", and releasing your objects ASAP). Moving your application into a COM object would also tremendously speed up the process.

You also can't manage permissions and file and folder attributes with the FSO. A great way to implement security would be to create the guestbook file we described earlier as read-only, and then change the attribute to writeable only when we need it, and immediately change it back. This method is often used in CGI and Perl scripts, but unfortunately, there's no pleasant way to do this with the FSO.

What else can I do?

There are a lot of really cool features in the FSO model that most people aren't aware of. These are the type of features that you normally find out about after you did things the hard way, and you end up saying "If only I knew that before!"

I'll briefly list the not-so-common but cool functions here.

Little Known FSO Features
GetSpecialFolder Method Returns the path to a special Windows folder: the Windows installation folder; the system folder; and the Windows Temporary folder. Syntax: FSO.GetSpecialFolder([0, 1, or 2])
GetTempName Method Returns a randomly generated temporary file or folder name. Useful when you need to store temporary data (i.e. when you run into the file size limitation described above).
GetAbsolutePathName Method Returns the absolute path of a folder (similar to Server.MapPath). For example, FSO.GetAbsolutePathName("region") will return something like "c:\mydocs\myfolder\region"
GetExtensionName Method Returns the extension for the last item in a path (i.e. FSO.GetExtensionName("c:\docs\test.txt") will return txt)
GetBaseName and GetParentFolder Methods Returns the base and parent folder name respectively of last item in a path (i.e. FSO.GetParentFolder ("c:\docs\mydocs") will return 'docs')
Drives Property Returns a collection of all the drive objects available on the local machine. This is helpful if you ever want to build an explorer type interface.

You'll want to make sure you build in robust error handling routines though, because some of these above functions will return nasty errors if the specified file or folder does not exist.


As we can see, the FSO is very nifty, and we only touched the tip of the 'berg here. Many of these features are implemented on big-name sites, and many of them pay big bucks for applications that can do this type of thing. Meanwhile the little 'ol FSO sits by and waits for someone to come across and use his power! Um..whoops, did I say that aloud?

The takeaway here is that you can build very powerful applications with the FSO, as well as accomplish some simples tasks more easily. Keep this one in your toolbelt!

Happy scripting!

About the Author

Chris Payne Currently lives in the Boston area. He has been building database driven web sites for several years. In February 2000, he cofounded Enfused Media, Inc, a web development/gaming firm. The first development from EMI was www.enfused.com, a massive gaming portal for gamers as well as the gaming business. His offline time is spent with his fiance and their tropical fish. Email: clpayne@enfused.com

This article was originally published on January 10th, 2008

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date