The reader is expected to have a basic working knowledge of Visual Basic Data
Types, Arrays, Loops and Library Functions.

II. BASIC RELATIONSHIPS

You might have heard several terms in File Handling such as Fields, Records etc.
but may not know what they mean.
To understand it simply remember this set of relationships:
8 Bits = 1 Byte/Character
Many Bytes/Characters = 1 Field (or String)
Many Fields = 1 Record
Many Records = 1 File
Many Files = 1 Database

III. INTRODUCTION

As far as Visual Basic 6 is concerned, there are three modes in which a file can
be accessed.

1) Text Mode (Sequential Mode)

2) Random Access Mode

3) Binary Mode

In the Text Mode, data is ALWAYS written and retrieved as CHARACTERS.
Hence, any number written in this mode will result in the ASCII Value of the
number being stored.
For Example, The Number 17 is stored as two separate characters "1" and "7".
Which means that 17 is stored as [ 49 55 ] and not as [ 17 ].

In the Binary Mode, everything is written and retrieved as a Number.
Hence, The Number 17 Will be stored as [ 17 ] in this mode and
characters will be represented by their ASCII Value as always.

One major difference between Text Files and Binary Files is that Text Files
support Sequential Reading and Writing. This means that we cannot read or write
from a particular point in a file. The only way of doing this is to read through
all the other entries until you reach the point where you want to 'actually'
start reading.
Binary Mode allows us to write and read anywhere in the file. For example we can
read data directly from the 56th Byte of the file, instead of reading all the
bytes one by one till we reach 56.

Just like the Binary Mode, the Random Access Mode allows us to gain
instant access to any piece of information lying anywhere in the file at a cost.
In this case, we must standardize each piece of information.
For example, if we need to store a few names in the file Random Access Mode
requires us to mention the length of the 'Names' Field.

Some Names might not fit and for the shorter names the space is inefficiently
used. Random Access Mode allows us to read or write data at a particularrecord position rather than a byte position like in Binary Mode.

A Good Example of Sequential Mode is the Audio Cassette. If we have to
listen to a particular Song in the cassette, we have to play the tape right from
the beginning until we reach the beginning of the song.
And so obviously, CDs, DVDs etc. are examples of Binary Mode ( and even Random
Access Mode )

You should read Part-II of the VB6 File Handling tutorial series if you wish to read about Access Permissions and Locks. Read Section VII : ACCESS-LOCKS for more information on Locks and Access Permissions for Sequential Files.

III. SEQUENTIAL FILE HANDLING

To open a File in Sequential Mode, we need to use the Open Command like this:

Open <FILENAME> For <MODE> As <FILE#>
FILENAME : Contains the Path of the File to be opened.
MODE : Can be INPUT, OUTPUT or APPEND
FILE# : Any number from 1 to 255 preceded by a #

Each File irrespective of its mode requires a file handle(FILE#). All operations
on the file are done using the File Handle. The File Handle can be any number
from 1 to 255, and this number is preceded by the # character.

Files can be opened in three modes in Sequential File Handling Mode and they are
used in different situations as shown.

INPUT -> Used to Read From a File.
OUTPUT -> Used to Write to a File.
APPEND -> Used to Write to a File.

Hence, to open a file Contacts.txt in Input Mode we use the Open Command like
this:

Open "C:\Contacts.txt" For Input as #1

Notice that the path of the file is mentioned. If the path is not mentioned,
Visual BASIC assumes the file to be in the current directory.

To close the file we use the CLOSE Command like this:

Close #1

This Closes the File referred to by File Handle 1. The Close Command can also be
called with no arguments, but in this case it would close all open Files.

NOTE: Closing a File is mandatory after your I/O operations are completed. Not
closing a file can lead to loss of data.

For the rest of this section, assume the Contacts.txt file to contain the
following data:

"Sanchit",9811122233
"Friend",9812345634
"Enemy",9821630236

Now let us try to read from this file. We can read each line separately into a
string by using the Line Input Command. Take a look at this snippet:

Dim tmp as String
Open "C:\Contacts.txt" For Input as #1
Line Input #1, tmp
Close #1
Msgbox tmp

As you can see, the MessageBox displays: "Sanchit",9811122233

The Line Input Command extracts the line currently pointed to by the File
Pointer (this happens internally) into a string.

If we add another Line Input Command after the first, the MessageBox will
display: "Friend",9812345634

We can now write a Program that displays the entire contents of a file in a
MessageBox, using the Line Input Command.

The Eof() Function (Discussed in Section V.) determines if the End of the
specified file has been reached.

If you look at the original file, there are newline characters after every entry.
But when we use Line Input or any other Sequential Mode Function, the Newline
character is never considered. Hence the Output shown is without the Newline
Characters.

Now what if we wanted to separate the two fields and store the Name and Phone
Number into two variables?
We certainly can, with the help of the Input #<File> Command.

To separate the two fields into two variables we can use it like this:

To use the Input# Command, we must know the exact number and type of fields
present in a data file. Remember that in case the argument types are mismatched,
it results in an Error.

That's all there is to read a file in Sequential Mode. Now let us turn our
attention to writing data into a file.

As we have seen earlier, there are two modes for writing data into a file,OUTPUT mode and APPEND mode.

The OUTPUT Mode creates a new file irrespective of whether a file with the same
name exists or not. In other words, If no file by the specified filename is
present, a new file is created else the previous file is overwritten (rather
deleted and a new file with the same name is created).

The APPEND Mode does exactly what the OUTPUT Mode does but with a difference. It
can also create a file if it doesn't exist in the directory. But if the file is
present, it adds data (provided by the programmer) to the end of the file. This
means that we can add new information without destroying the information that
was present before.
This mode can be used in a Web-Access Logger Program. Everytime a User accesses
a webpage, the program can add the visitor's IP Address to a given file. If the
OUTPUT Mode was used in this case, only the most recent visitor's IP Address
would be stored in the file.

Unlike Reading from Files which is done by using only the Input# Command,
Writing to a File can be accomplished by using two commands, Print# and Write#.
Their Syntax is exactly like that of the Input# Command.

Consider the following code snippet:

Open "C:\names_database.txt" For Output As #1
Print #1, "My Phone number is 12345678", 910
Write #1, "My Phone number is 12345678", 910
Close #1
End

If you open the names_database.txt file in a Text-Editor you will see the
contents of the file as follows:

My Phone number is 12345678 910
"My Phone number is 12345678",910

With Print#, what appears in the file would be the exact image of what
would appear on the screen (i.e. No quotes around strings and no commas)
In this case the file will contain the string:"My Phone number is 12345678"
followed by 2 spaces, numeral 9, numeral 1, numeral 0, another space followed by
two characters (0xD 0xA) That make up the Carriage Return/Line Feed Combination.

The Write# Command Writes Strings into the File with the Quotes, Numbers
as they are and separates different fields by using a comma.
It is good practice to use this command instead of Print# since the Input#
Command is able to separate Records into Fields from Records that are written by
the Write# Command. (It can work with Print# too, but it requires additional
code and yet may not work as expected)

We must remember one important thing about Print# and Write#. After every Print#
or Write# Command, the respective command automatically inserts a Carriage
Return/Line Feed Characters (0xD 0xA) and hence every subsequent Write# or Print#
Command will write data to the next line in the file. If you wish to write data
on the same line in the file, add it to the same Print#/Write# Command.
Example:

Write #1,"ABCD"
Write #1,123
Write #1,"ABCD",123

OUTPUT:

"ABCD"
123
"ABCD",123

Write# has a major advantage over Print# when it comes to Storage of Strings.
In the previous example, the string:"My Phone number is 12345678" was stored as
"My Phone number is 12345678 " (with two additional spaces) by using Print#.
Sometimes 7 Additional Spaces are stored, at times 3 or 5 and the number varies
with each string. Hence it becomes difficult to figure out if the 'additional'
spaces are actually a part of the string or are added by VB itself. This also
makes it difficult to separate a record into different fields.
The Write# Command on the other hand stores the entire string within
quotes, so there is no doubt about the content as well as the length of the
string.
MSDN offers the same advice.

Quote

If, at some future time, you want to read the data from a file using the Input#
statement, use the Write # statement instead of the Print # statement to write
the data to the file. Using Write# ensures the integrity of each separate data
field by properly delimiting it, so it can be read back in using Input#.
Using Write# also ensures it can be correctly read in any locale.

But incase you are wondering why the number of additional spaces keep changing
each time, here is the reason why it happens.

IV.1) PRINT# AND THE PROBLEM WITH HANDLING STRINGS

[KNOWLEDGE OF THIS ABNORMALITY IS NOT REQUIRED FOR UNDERSTANDING FILE HANDLING.
YOU MAY SKIP THIS SECTION IF YOU WISH]

Unlike Languages such as C/C++,Java etc. where the length of a string has to be
specified beforehand, Visual Basic does not force the Programmer to do this.
If the Programmer does not specify the length of the string at compile time,
Visual Basic has its own way of allocating memory based on the strings contents.
Click here to see how Strings are internally stored in VB6.

As a result, extra memory may get allocated which results in the additional
spaces in the data files.
You can remove this shortcoming by either using Write# or by providing the
length of the string at compile time. The Syntax to do this is:

Dim <variable_name> As String * <Length_of_String>

V. SEQUENTIAL FILE HANDLING FUNCTIONS

FreeFile()
DESCRIPTION : Returns an Integer representing the nextfile number available
for use by the Open statement.

SYNTAX : FreeFile[(rangenumber)]
The optional rangenumber argument is a Variant that specifies
the range from which the next free file number is to be
returned. Specify a 0 (default) to return a file number in the
range 1 – 255, inclusive. Specify a 1 to return a file number
in the range 256 – 511.

USE : FreeFile() is used to avoid using a file handle that is already
in use.

EOF()
DESCRIPTION : Returns anInteger containing the Boolean value True when the
end of a file opened for sequential Input has been reached.

USE : Seek() is used to get the Byte Position where the Next
Operation will take place.

VI. SEQUENTIAL FILE HANDLING EXAMPLES

That is all you need to know about Sequential File Handling.
I shall now mention few examples which use File Handling Techniques to help
you understand it better.

1) Getting the Number of Lines in a File.

Dim counter As Long, tmp As String
counter = 0
Open "c:\names_database.txt" For Input As #1
While Not EOF(1)
Line Input #1, tmp
counter = counter + 1
Wend
Close #1
MsgBox counter ' Outputs the Number of Lines in a File.

Dim delFirstName As String ' String that contains Record to be Deleted
Dim fName As String, lName as String
delFirstName = "Sanchit"
Open "c:\test.txt" For Input As #1
Open "c:\test.tmp" For Output As #2
While Not EOF(1)
Input #1, fName, lName
If fName <> delFirstName Then
Write #2, fName, lName
End If
Wend
Close #1, #2
Kill ("c:\test.txt") ' Deletes the Original File
Name "c:\test.tmp" As "c:\test.txt" ' Renames the New File

3)Deleting a Record From a File (Using Arrays Only Method)
ASSUMPTION : The File test.txt contains:
"Sanchit"
"ABCD"
"Steve"
"XYZ"

Dim strdelstring As String, tmp As String
Dim file_length As Long, i as Long
strdelstring = "Steve"
file_length = 0
Open "C:\test.txt" For Input As #1
' First We Find the Number of Records so that we can allocate an Array
' To Accomodate all records
While Not EOF(1)
Line Input #1, tmp
file_length = file_length + 1
Wend
Close #1
' Now allocate the Array
ReDim arrdata(file_length) As String
' And Store the Entire File's Contents into the Array
Open "c:\test.txt" For Input As #1
For i = 1 To file_length
Input #1, arrdata(i)
Next i
Close #1
' Now Open the Same File Again in Output Mode and Write the Contents
' Back into the File except that which is supposed to be deleted.
Open "c:\test.txt" For Output As #1
For i = 1 To file_length
If arrdata(i) <> strdelstring Then
Write #1, arrdata(i)
End If
Next i
Close #1

I'm trying to have a program that let's the user determine where to save a file(containing a lot of variables) that can be read the next time the program is opened. both screens have drive,directory, and file listboxes for choosing the location.

Hi,
I have an array that I want to write# to a file with all the items on a single line e.g.
211, "Tim",#FALSE#
212, "John",#TRUE#
etc
My code looks like this (not pretty I know)

oFile rsTrans, "select * from trans order by acs, count"
c = App.Path & "\Trans.gts"
Open c For Output As #1
do while not rstrans.eof
For a = 0 To rsTrans.Fields.Count - 1
Write #1, rsTrans.Fields(a).Value
Next a
Close #1
rstrans.movenext
loop

The problem is I don't know all the time how many fields there will be to write out so I used a loop BUT write sends each field out as a separate record like this
211
"Tim"
#FALSE#
212
"John"
#TRUE#

, can you help please.

Sorry, I've answered my own question. Playing with it I found that adding a ; (semicolon) at the ned of the Write statement did the trick. Memory dragged up from the old Dos days.

My application is supposed to write to a log for 7 days and after 7 days of createDate, the file is moved to an Archive folder. After this, a new log file is written for the current run. The archiving and new log file creation of course happens in a single run of the application.

The issue is when a new file is getting created, it takes the create timestamp of archived log file. This is making my application archive the logs everyday.

I use the following when writing the log:
Open OutputFile For Append As iFileNum
Any suggestions?