File I/O - VisualBasic Examples


File Manager Commands

Change Directory ChDir "c:\path"
Make Directory MkDir "c:\path"
Remove Directory RmDir "c:\path"
Change Drive ChDrive "d"
Rename a File Name "test.txt" as "string.tst"
(May fail if directories are not specified)
Delete a File Kill "c:\*.tst"
Search for File temp$ = Dir ("c:\*.tst")
Current Drirectory temp$ = CurDir ("d") ' Drive letter is optional
Get File Attributes temp = GetAttr ("c:\filename.tst")
Get File Mode temp = FileAttr ("c:\filename.tst", attributes)
Set File Attributes SetAttr "c:\filename.tst", vbReadOnly
Get File Length FileLen ("c:\filename.tst")
Get File Date/Time tempDate = FileDateTime ("c:\filename.tst")
Set File Date/Time ????


File I/O Commands

Open File for I/O Open "c:\filename.tst" For Input As 3
fn = FreeFile ' next unused number
Open "c:\filename.tst" For Input As fn
Get File Mode temp = FileAttr (3, 1)
Write to File Write 3,
Write to File Print 3,
Read From File Input 3,
Read From File Get 3,
Read From File Line Input #FileHandle, TextLine$
Current Location tempNum = Seek (3)
Current Location tempNum = Loc (3)
Length of File tempNum = LOF(3)
End of File Do While Not EOF(3) .. Loop
Close File Close 3
Closes All Files Reset

Write places strings in double quotes, separates values with commas, and adds a CR/LF pair at the end of each command. Read the data back with Input.

Print does not add extra delimiters, but does concatenate a final CR/LF to each line. The CR/LF can be suppressed by ending the command with a semicolon (;). (This trick has been available in every Basic I've used, but it is not documented in the VB 6.0 Help.) Read it back with Line Input. (Line Input assumes a DOS type ASCII input file where each line is terminated with CR/LF. It does not recognize the unix line termination character.)


File Access via a FileSystemObject

VB 6.0 provides a poorly documented FileSystemObject for File I/O. Help on these commands was found be basically "stumbling" onto them. This is the only File I/O method supported via VBScript. The basic syntax is
  Set fs = CreateObject("Scripting.FileSystemObject")
  Set a = fs.CreateTextFile("c:\testfile.txt", True)
  a.WriteLine("This is a test.")
  a.Close
See the help for additional details.


Standard Open File Dialog

Based on the provided help, there is no way to open a file using the provided components. For instance

Selecting a File to Open

First install the Common Dialog ActiveX Component - comdlg32.ocx - in the ToolBox.
  Dim TestFile$  ' String variable
  CMDialog.Filter = "Test (*.tst)|*.tst"
  CMDialog.InitDir = "C:\SomePath"
  CMDialog.Action = 1 ' VB 4.0 way to select FileOpen
                      ' Still works in VB 6.0
  CMDialog.ShowOpen   ' VB 6.0 way to select FileOpen


  TestFile$ = CMDialog.FileName ' = "" if the Cancel button is pressed

  If TestFile$ <> "" Then
    Main_UIForm.Caption = _
       "Application Name or Function - " + CMDialog.FileTitle
    Call SomeProcedure(TestFile$)
  End If
CMDialog.FileName File name and path
CMDialog.FileTitle File name without the path

Notice that by default, CMDialog changes the default path! Setting a bit in the flag property will prevent this.

The help for the common Dialog FileName property says to use the Path property to get the related path. However, if you use CMDialog.Path you get an

Compile error because there is no such property.

Specifying a Drive and Path

The File Open control is worthless for specifying a path. Instead you should use the DirListBox control. Notice that the Path property does not reflect the currently selected item. Therefore, I use
  Select_Directory_UIForm.Tag = UIDirListBox.List(UIDirListBox.ListIndex)
to return the selected directory. Null means that Cancel was selected.

Use the DriveListBox control to change drives. The following code is adequate.

  Private Sub UIDriveListBox_Change()
    UIDirListBox.Path = UIDriveListBox.Drive
  End Sub


Opening and Reading a File

  Dim TextLine$, Filename$
  Dim FileHandle as Integer

  Filename$ = "test.txt"

    ' Test if the file exists
  If Dir(Filename$) = "" Then Exit Sub

  FileHandle = FreeFile ' This is safer than assigning a number

  Open Filename$ For Input As #FileHandle

  Do While Not EOF(FileHandle)        ' Loop until end of file
   Line Input #FileHandle, TextLine$  ' Read line into variable
    ' Your code here
  Loop

  Close #FileHandle
Line Input assumes a DOS type ASCII input file where each line is terminated with CR/LF. It does not recognize the unix line termination character.

File SaveAs

First install the Common Dialog ActiveX Component - comdlg32.ocx - in the ToolBox. (See above)
  Dim fs 'As FileSystemObject
  Dim OldPath$
  OldPath$ = CurDir   ' CMDialog will change the current path
  Set fs = CreateObject("Scripting.FileSystemObject")
  If Not fs.FileExists("Test.txt") Then Exit Sub
  
  CMDialog.Flags = cdlOFNHideReadOnly + cdlOFNExplorer
  CMDialog.Filter = "Test (*.tst)|*.tst"
  CMDialog.FileName = "" ' This is the value returned if Esc/Cancel

  CMDialog.Action = 2 ' VB 4.0 way to select FileSaveAs
  CMDialog.ShowSave   ' VB 6.0 way to select FileSaveAs

  TestFile$ = CMDialog.FileName ' = "" if the Cancel button is pressed

  If TestFile$ <> "" Then
      ' If OverWrite, ask if ok
    If Dir(TestFile$) <> "" Then
      Select Case MsgBox("Overwrite existing file?", vbOKCancel)
        Case vbOK
          Kill (TestFile$) ' of course, this is wrong
                           ' re-name the old file and erase it
                           ' after the new file is written
        Case Else
          Exit Sub
      End Select
    End If
    
    Name OldPath$ & "\Test.txt" As TestFile$
  End If
Notice that CMDialog changes the default path!


Testing for a Legal Filename

' Directory and file names can not contain the following
'      \ / : * ? " < > |
' Though allowed, the ampersand will also cause problems in NT
' Paths can contain  : \
'
  Dim crlf$, badChars$, badChars2$, i, tt$
  crlf$ = Chr(13) & Chr(10)
  badChars$ = "\/:*?""<>|"           ' For Testing, no spaces
  badChars2$ = "\ / : * ? "" < > |"  ' For Display, has spaces

      ' Check for bad characters
    For i = 1 To Len(tt$)
      If InStr(badChars$, Mid(tt$, i, 1)) <> 0 Then
        temp = MsgBox("A directory name may not contain any of the following" _
               & crlf$ & crlf$ & "     " & badChars2$, _
               vbOKOnly + vbCritical, _
               "Bad Characters")
        Exit Sub
      End If
    Next i


Testing for the Existance of a File

There are 2 ways to determine the existance of a file
  Dim fs ' The help does not say what type this should be
         '   therefore, I tried a variant
  Set fs = CreateObject("Scripting.FileSystemObject")
  If Not fs.FileExists("Test.tst") Then Exit Sub
Scripting is a keyword which is not documented in the help outside this one example.
Use the Dir function to check if specific files and directories exist. The first call to Dir should contain a path and any wild cards. Subsequent calls without parameters will return the next matching filename or a null string if there is no match.
  Temp$ = Dir("*.tst")             ' Get the first tst file
  Temp$ = Dir("c:\", vbDirectory)  ' Get the first directory name
                                   '  in the indicated path
  Do While Temp$ <> ""             ' Loop till there is no match
    ' Place main routine here
    Temp$ = Dir                    ' Get next matching filename
  Loop
Both Dir and Dir(, vbDirectory) ignore the file attributes and return the next "file" in the last referenced directory. (Under DOS, sub-directories are simply files with the Directory attribute set.) Use GetAttr to test specific attributes. Remember that all sub-directories contain references to files named "." and ".."


Testing for the Existance of a Drive

The following code is not generally acceptable for checking the existance of a drive.
    ' Returns null if the drive does not exist
    '   or if the root directory is empty
  a$ = Dir ("C:\")
A better solution is
(Source: Trevor Daniel at British Telecom via comp.lang.basic.visual.misc)
Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA"
              (ByVal sDrive As String) As Long
 
Private Function DriveType(DriveStr As String) As String
  Dim DriveTypeLong As Long
  Dim aa As String
  Const DRIVE_TYPE_UNDETERMINED = 0
  Const DRIVE_ROOT_NOT_EXIST = 1
  Const DRIVE_REMOVEABLE = 2
  Const DRIVE_FIXED = 3
  Const DRIVE_REMOTE = 4
  Const DRIVE_CDROM = 5
  Const DRIVE_RAMDISK = 6
  aa = DriveStr & ":"
  DriveTypeLong = GetDriveType(aa)
  Select Case DriveTypeLong
    Case DRIVE_TYPE_UNDETERMINED
        DriveType = aa & " is not a recognised drive type"
    Case DRIVE_ROOT_NOT_EXIST
        DriveType = "The drive " & aa & " does not exit"
    Case DRIVE_CDROM
        DriveType = aa & " is a CD-ROM driver"
    Case DRIVE_FIXED
        DriveType = aa & " is a Hard Disk"
    Case DRIVE_RAMDISK
        DriveType = aa & " is a RAM Disk"
    Case DRIVE_REMOTE
        DriveType = aa & " is a network drive"
    Case DRIVE_REMOVEABLE
        DriveType = aa & " is a Floppy Disk"
  End Select
End Function
In order to see all the Windows API file functions, search the MS Visual Studio help for GetDriveType and click on File Functions.

It is not clear why the Windows constants need to be manually defined.


Author: Robert Clemenzi - clemenzi@cpcug.org
URL: http:// cpcug.org / user / clemenzi / technical / Languages / VisualBasic / VBFileIO.htm