FileSystemTools module

FileSystemTools is the standard module that holds the code of the tbFileSysTools package: path functions, file and folder operations, whole-file text and byte input and output, and the functions that return File, Folder, Drive and TextStream objects. A project that references the package calls its procedures by name, with no object to create. The FileSystemObject class has the same procedures as members of a COM object, for code that was written for the Scripting Runtime.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

Dim path As String
path = BuildPath(work, "notes.txt")

' Write a string as UTF-8 with a byte-order mark, then ask what the file holds.
StringToTextFile "caf" & ChrW$(233) & vbCrLf & "ok", path, encUtf8Bom
Debug.Print GetFileEncoding(path) = encUtf8Bom    ' True
Debug.Print GetFileLineEnding(path) = nlWindows   ' True
Debug.Print Len(TextFileToString(path))           ' 8

DeleteFolder work

The procedures, by purpose:

The enumerations that the procedures take are described at the end of the page: TextEncoding, NewlineType, IOMode, SpecialFolderConst, FileAttribute, FileVersionSource and StandardStreamTypes.

Conventions

These rules apply to every procedure on the page. Each entry states only what departs from them.

Paths.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

' A folder 12 levels deep, with a path of more than 300 characters.
Dim deep As String, i As Long
deep = work
For i = 1 To 12
    deep = BuildPath(deep, String$(25, "d"))
Next
CreateFolder deep, True

Dim path As String
path = BuildPath(deep, "note.txt")
StringToTextFile "hello", path
Debug.Print Len(path) > 300      ' True
Debug.Print FileExists(path)     ' True
Debug.Print TextFileToString(path)   ' hello

DeleteFolder work

Wildcards. CopyFile, CopyFolder, DeleteFile, DeleteFolder, MoveFile and MoveFolder accept * and ? in the last component of the path that names what to act on. A wildcard in a destination is error 5. A pattern that matches nothing is an error, as described for each procedure. A failure part-way through a wildcard operation leaves the earlier matches changed; the sample under DeleteFile shows it.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
StringToTextFile "1", BuildPath(work, "a.txt")
StringToTextFile "2", BuildPath(work, "a.txtx")

' The 8.3 name of a.txtx is different from its name, and it ends in .TXT.
Debug.Print GetFile(BuildPath(work, "a.txtx")).ShortName <> "a.txtx"   ' True
Debug.Print GetFilePaths(work, "*.txt").Count                          ' 2
DeleteFile BuildPath(work, "*.txt")
Debug.Print GetFilePaths(work).Count                                   ' 0

DeleteFolder work

Errors. A procedure raises a run-time error with the number VB6 uses for the same failure. The error numbers, and the Windows failures that map to them, are in Errors, which also lists the errors that version 1.1.1.0 raises where the Scripting Runtime raises another. Err.Source is the name of the operation, such as CopyFile, and Err.Description names the path; the errors of OpenTextFile and its relatives have an empty Err.Source and only the standard text of the number.

Encodings. A text procedure takes a TextEncoding member. Its value is a Windows code page; a negative value is the same code page with a byte-order mark (BOM). On reading, encAutoDetect means: find the encoding from the first bytes of the file. On writing, encAutoDetect means encUtf8. A BOM that the file holds always decides the encoding on reading, whatever the argument says.

A directory junction or symbolic link is a folder that stands for another folder. In version 1.1.1.0, CopyFolder, DeleteFolder and GetFilePaths with recursive enter one like an ordinary folder. Folder.Size does not: it skips the link, so each file is counted once, where it is stored. The Scripting Runtime enters a link when it adds up the size, so it counts a target twice when the target is in the same tree.

The sample builds a tree with a link to one of its own folders, and a second tree with a link to a folder outside it. DeleteFolder of the second tree deletes the file in the outside folder.

Dim work As String, tree As String, sh As Object
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
tree = BuildPath(work, "tree")
CreateFolder BuildPath(tree, "sub"), True
StringToTextFile String$(500, "x"), BuildPath(tree, "file1.txt")
StringToTextFile String$(1000, "y"), BuildPath(tree, "sub\file2.txt")
Set sh = CreateObject("WScript.Shell")
sh.Run "cmd /c mklink /J """ & BuildPath(tree, "link") & """ """ & BuildPath(tree, "sub") & """ >nul", 0, True

Debug.Print GetFolder(tree).Size                                              ' 1500
Debug.Print CreateObject("Scripting.FileSystemObject").GetFolder(tree).Size   ' 2500
Debug.Print GetFilePaths(tree, , , , True).Count                              ' 3
CopyFolder tree, BuildPath(work, "copy")
Debug.Print FileExists(BuildPath(work, "copy\link\file2.txt"))                ' True
sh.Run "cmd /c rmdir """ & BuildPath(tree, "link") & """", 0, True

Dim target As String, tree2 As String
target = BuildPath(work, "target")
tree2 = BuildPath(work, "tree2")
CreateFolder target
CreateFolder tree2
StringToTextFile "keep me", BuildPath(target, "keep.txt")
sh.Run "cmd /c mklink /J """ & BuildPath(tree2, "link") & """ """ & target & """ >nul", 0, True
DeleteFolder tree2, True
Debug.Print FolderExists(tree2)                                               ' False
Debug.Print FolderExists(target)                                              ' True
Debug.Print FileExists(BuildPath(target, "keep.txt"))                         ' False

DeleteFolder work

Paths

BuildPath

Joins a folder path and a name.

Syntax: BuildPath ( path, name ) As String

path
required A String holding a folder path. It can be empty.
name
required A String holding the name of a file or folder, or a relative path.

Returns path and name joined by one backslash. Nothing is read from the disk, and neither string has to name anything that exists.

  • An empty path returns name, and an empty name returns path.
  • A backslash that ends path or starts name is not doubled.
  • A path that ends in a colon, a drive letter such as C:, is joined without a backslash: BuildPath("C:", "foo") returns C:foo, as the Scripting Runtime does.
  • A forward slash in either argument becomes a backslash: BuildPath("C:\a", "b/c") returns C:\a\b\c. The Scripting Runtime returns C:\a\b/c.

CleanFileName

Removes from a file name the characters that Windows does not allow.

Syntax: CleanFileName ( fileName [, replaceChar ] ) As String

fileName
required A String holding a file name. It is a name, not a path: the path separators are among the characters that are removed.
replaceChar
optional A String that takes the place of each removed character. Default: an empty string, which deletes them.

Returns the name after these steps, in this order:

  1. Each of the characters \ / : * ? " < > | and each control character (codes 0 to 31) is replaced by replaceChar.
  2. Spaces and dots at the end, and spaces at the start, are removed. This includes any that replaceChar put there. Dots at the start stay.
  3. If the part of the name before its first dot is a reserved device name (CON, PRN, AUX, NUL, COM0 to COM9 and LPT0 to LPT9, in any letter case, trailing spaces ignored), replaceChar is added to that part, or an underscore when replaceChar is empty. Windows treats such a name as a device even with an extension.

The length of the name is not checked.

Debug.Print CleanFileName("report: Q1/Q2?.txt")        ' report Q1Q2.txt
Debug.Print CleanFileName("report: Q1/Q2?.txt", "_")   ' report_ Q1_Q2_.txt
Debug.Print CleanFileName("NUL.txt")                   ' NUL_.txt
Debug.Print CleanFileName("notes. ")                   ' notes
Debug.Print CleanFileName("com3")                      ' com3_
Debug.Print CleanFileName("CON ")                      ' CON_
Debug.Print CleanFileName("Aux.tar.gz", "-")           ' Aux-.tar.gz
Debug.Print CleanFileName(".gitignore")                ' .gitignore

GetAbsolutePathName

Returns the full path for a path specification.

Syntax: GetAbsolutePathName ( path [, baseDirectory [, useLongPathPrefix ] ] ) As String

path
required A String holding an absolute or relative path. The path does not have to exist.
baseDirectory
optional A String holding the folder against which a relative path is resolved. Default: an empty string, which means the current directory. An absolute path ignores it. A path of the form C:name (a drive without a backslash) uses it only when baseDirectory is on the same drive.
useLongPathPrefix
optional A Boolean. When True, the result starts with \\?\, or with \\?\UNC\ for a network path. Default: False.

Returns the path with . and .. resolved and forward slashes turned into backslashes. The work is done on the text, and the disk is not read. A backslash at the end is removed, except for a drive root, which keeps it and gets an uppercase drive letter: c:\ becomes C:\. The rest of the path keeps the letter case it was given.

Raises error 52 when Windows cannot form a full path from the text. An empty string is such a case: GetAbsolutePathName("") raises error 52, where the Scripting Runtime returns the current directory. GetAbsolutePathName(".") returns the current directory in both.

Debug.Print GetAbsolutePathName("a\..\b", "C:\base")        ' C:\base\b
Debug.Print GetAbsolutePathName("\x", "D:\base\deep")       ' D:\x
Debug.Print GetAbsolutePathName("C:name", "C:\base")        ' C:\base\name
Debug.Print GetAbsolutePathName("c:\")                      ' C:\
Debug.Print GetAbsolutePathName("C:\Temp\")                 ' C:\Temp
Debug.Print GetAbsolutePathName("C:/a/./b/../c")            ' C:\a\c
Debug.Print GetAbsolutePathName("C:\x", , True)             ' \\?\C:\x
Debug.Print GetAbsolutePathName("\\srv\sh\f", , True)       ' \\?\UNC\srv\sh\f

GetBaseName

Returns the name of the last component of a path, without its extension.

Syntax: GetBaseName ( path ) As String

path
required A String holding a path. It does not have to exist.

The extension is what follows the last dot of the name. A name without a dot is returned whole, and a name that starts with its only dot has an empty base name: GetBaseName("C:\work\.gitignore") returns an empty string, and GetExtensionName returns gitignore. The work is done on the text.

GetDriveName

Returns the drive part of a path.

Syntax: GetDriveName ( path ) As String

path
required A String holding a path.

Returns a drive letter and a colon, C:, for a path that starts with one, and \\server\share for a network path. Neither has a trailing backslash. Returns an empty string for any other path, and for a network path that names a server but no share.

GetExtensionName

Returns the extension of the last component of a path.

Syntax: GetExtensionName ( path ) As String

path
required A String holding a path.

Returns what follows the last dot of the name, without the dot, or an empty string when the name has no dot. See GetBaseName.

GetFileName

Returns the last component of a path.

Syntax: GetFileName ( path ) As String

path
required A String holding a path.

Returns the name after the last backslash. Separators at the end of the path are ignored: C:\work\data\ returns data. The drive part is dropped: C:name returns name. A drive root, C:\, and a network root, \\server or \\server\share, return an empty string. The work is done on the text.

GetParentFolderName

Returns the path of the folder that holds the last component of a path.

Syntax: GetParentFolderName ( path ) As String

path
required A String holding a path.

Returns the text before the last separator. The parent of a folder directly under a drive root is the root, with its backslash: C:\work returns C:\. Returns an empty string for a name with no separator, for a drive root, and for a network root (\\server or \\server\share). The work is done on the text.

Dim p As String
p = "C:\Projects\App\docs\readme.final.txt"
Debug.Print GetFileName(p)                      ' readme.final.txt
Debug.Print GetBaseName(p)                      ' readme.final
Debug.Print GetExtensionName(p)                 ' txt
Debug.Print GetParentFolderName(p)              ' C:\Projects\App\docs
Debug.Print GetDriveName(p)                     ' C:
Debug.Print BuildPath("C:\Projects", "App")     ' C:\Projects\App
Debug.Print BuildPath("C:\Projects\", "\App")   ' C:\Projects\App

Roots and names without a folder:

Debug.Print GetFileName("C:\work\data\")               ' data
Debug.Print GetFileName("C:name")                      ' name
Debug.Print GetFileName("C:\") = ""                    ' True
Debug.Print GetFileName("\\server\share") = ""         ' True
Debug.Print GetParentFolderName("C:\work")             ' C:\
Debug.Print GetParentFolderName("C:\") = ""            ' True
Debug.Print GetParentFolderName("\\srv\sh\dir")        ' \\srv\sh
Debug.Print GetParentFolderName("\\srv\sh") = ""       ' True
Debug.Print GetDriveName("\\srv\sh\x")                 ' \\srv\sh
Debug.Print GetDriveName("\\srv") = ""                 ' True
Debug.Print GetBaseName("C:\work\.gitignore") = ""     ' True
Debug.Print GetExtensionName("C:\work\.gitignore")     ' gitignore

GetRelativePath

Returns the path that leads from one path to another.

Syntax: GetRelativePath ( basePath, targetPath [, basePathIsFolder [, trimLeadingDotSlash ] ] ) As String

basePath
required A String holding the path to start from.
targetPath
required A String holding the path to reach.
basePathIsFolder
optional A Boolean. True (default) treats basePath as a folder. False treats it as a file when it exists as one, and the relative path starts from the folder that holds it. A basePath that does not exist is treated as a file when this is False.
trimLeadingDotSlash
optional A Boolean. Windows starts a path that goes down with .\. True (default) removes it, so the result is src and not .\src. False keeps it.

Both paths are first made absolute with GetAbsolutePathName. A targetPath that exists as a folder is treated as one; any other, one that does not exist included, is treated as a file. So GetRelativePath("C:\a", "C:\a") returns ..\a when the folder C:\a does not exist.

Returns the absolute targetPath when there is no relative path, for example when the two paths are on different drives, and when only targetPath is longer than 260 characters.

Debug.Print GetRelativePath("C:\Projects\App", "C:\Projects\Lib\core.txt")   ' ..\Lib\core.txt
Debug.Print GetRelativePath("C:\Projects\App", "C:\Projects\App\src")        ' src
Debug.Print GetRelativePath("C:\Projects\App", "D:\Data")                    ' D:\Data
Debug.Print GetRelativePath("C:\a\b", "C:\a\b\c\d.txt", True, False)         ' .\c\d.txt
Debug.Print GetRelativePath("C:\a\b\f.txt", "C:\a\c.txt", False)             ' ..\c.txt

' The same relative path below a short base and below a base of 264 characters.
Dim shortBase As String, longBase As String
shortBase = "C:\" & String$(100, "a")
longBase = "C:\" & String$(130, "a") & "\" & String$(130, "b")
Debug.Print GetRelativePath(shortBase, shortBase & "\x\y.txt")           ' x\y.txt
Debug.Print GetRelativePath(longBase, longBase & "\x\y.txt") = "x\y.txt"   ' False

GetTempName

Returns a random name for a temporary file or folder.

Syntax: GetTempName ( [ prefix [, extension [, inFolder ] ] ] ) As String

prefix
optional A String put before the random part. Default: an empty string.
extension
optional A String put after the random part, with its dot. Default: .tmp. An empty string gives a name without an extension.
inFolder
optional A String naming a folder. The name returned does not exist in that folder at the time of the call. Default: an empty string, which does not check.

Returns prefix, eight random uppercase letters and digits, and extension: with the defaults, twelve characters such as K3F9Q2ZA.tmp. The Scripting Runtime returns rad and five hexadecimal digits, such as rad15093.tmp. The result is a name, not a path, and nothing is created. The check against inFolder does not reserve the name, which another process can take before the caller creates it.

Existence

DriveExists

Returns whether a drive exists.

Syntax: DriveExists ( drivePath ) As Boolean

drivePath
required A String that starts with a drive letter: C, C:, C:\ or a longer path on that drive.

Returns True when Windows has a drive with that letter. Returns False for a letter that is not in use, for any string that is not of one of those forms, and for a network path, which is not a lettered drive.

FileExists

Returns whether a file exists.

Syntax: FileExists ( filePath ) As Boolean

filePath
required A String holding a path.

Returns True when the path exists and is not a folder. Hidden and system files count. Returns False for an empty string, for a folder, and for a path that holds a wildcard.

FolderExists

Returns whether a folder exists.

Syntax: FolderExists ( folderPath ) As Boolean

folderPath
required A String holding a path.

Returns True when the path exists and is a folder, a drive root included. Returns False for a file.

Files and folders

CopyFile

Copies one or more files.

Syntax: CopyFile ( source, destination [, overwrite ] )

source
required A String naming the file to copy. The last component can hold the wildcards * and ?, which match files only.
destination
required A String naming the new file, or a folder. An existing folder, or a path that ends in a backslash, is a folder: the copy keeps the name of the source. A wildcard in destination is error 5.
overwrite
optional A Boolean. True (default) replaces an existing file. False raises error 58 when the destination file exists.

With a wildcard in source, the destination is a folder that must already exist, and each matching file is copied into it. The parent folder of a single destination file must exist too. A destination that is an existing folder gets the copy with or without a backslash at the end. The Scripting Runtime raises error 70 when the folder has no backslash.

Errors:

  • 53 when the source file does not exist, or a wildcard matches no file (a pattern that matches only folders counts as no match).
  • 76 when the folder of destination does not exist.
  • 58 when the destination file exists and overwrite is False.
  • 70 when Windows refuses: a destination file that is read-only, and a source that is a folder.

The Scripting Runtime raises the same numbers for a missing source, an existing destination with overwrite False, and a read-only destination.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder BuildPath(work, "backup"), True
StringToTextFile "a", BuildPath(work, "a.txt")
StringToTextFile "b", BuildPath(work, "b.txt")
StringToTextFile "c", BuildPath(work, "c.log")

CopyFile BuildPath(work, "*.txt"), BuildPath(work, "backup")
Debug.Print GetFilePaths(BuildPath(work, "backup")).Count   ' 2
DeleteFile BuildPath(work, "*.txt")
Debug.Print GetFilePaths(work).Count                        ' 1
DeleteFile BuildPath(work, "*.txt"), ignoreMissing:=True    ' nothing matches: no error

DeleteFolder work

CopyFolder

Copies a folder and everything in it.

Syntax: CopyFolder ( source, destination [, overwrite ] )

source
required A String naming the folder to copy. The last component can hold the wildcards * and ?, which match folders only.
destination
required A String naming a folder. A wildcard in it is error 5.
overwrite
optional A Boolean. True (default) replaces files that already exist in the destination. False raises error 58 at the first file that exists, and the files copied before it stay.

When destination is an existing folder, the source is copied into it, as a subfolder with the name of the source, whether or not destination ends in a backslash. Otherwise destination is the new folder, and its parent must exist. Subfolders that already exist in the destination are merged. With a wildcard in source, destination must be an existing folder, and each matching folder is copied into it.

The Scripting Runtime does this only when destination ends in a backslash. Without one, it copies the contents of the source straight into the existing folder: CopyFolder "src", "dst" puts f1.txt in dst with the Scripting Runtime, and in dst\src here.

Errors:

  • 76 when the source folder, a wildcard match, or the parent of the new folder does not exist.
  • 5 when destination is the source or lies inside it, which would copy the folder into itself.
  • 58 when a file exists and overwrite is False.

CreateFolder

Creates a folder.

Syntax: CreateFolder ( folderPath [, createIntermediates ] ) As Folder

folderPath
required A String naming the folder to create.
createIntermediates
optional A Boolean. False (default) creates only the last folder, so its parent must exist. True also creates the missing folders above it.

Returns the new Folder.

Errors:

  • 58 when a folder, or a file, with that path exists.
  • 76 when the parent does not exist and createIntermediates is False.
  • 52 when the last component holds a character that is not allowed in a name, the wildcards * and ? among them.
Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

On Error Resume Next
CreateFolder work              ' the folder exists now
Debug.Print Err.Number         ' 58
Err.Clear
CreateFolder BuildPath(work, "a\b\c")   ' the folders above are missing
Debug.Print Err.Number         ' 76
Err.Clear
On Error GoTo 0

CreateFolder BuildPath(work, "a\b\c"), True
Debug.Print FolderExists(BuildPath(work, "a\b"))   ' True

DeleteFolder work

DeleteFile

Deletes one or more files.

Syntax: DeleteFile ( filePath [, force [, ignoreMissing ] ] )

filePath
required A String naming the file to delete. The last component can hold the wildcards * and ?, which match files only.
force
optional A Boolean. True clears the read-only, hidden and system attributes of a file before deleting it. False (default) leaves them, and a read-only file cannot be deleted.
ignoreMissing
optional A Boolean. True does nothing when the path or the pattern matches no file. False (default) raises error 53.

A path that names a folder is error 53, whatever ignoreMissing is. A failure on one file of a wildcard stops the deletion, and the files before it stay deleted.

Errors: 53 when no file matches, a folder is named, or the folder of the path does not exist; 70 for a read-only file without force. The Scripting Runtime raises 53 and 70 in these cases too.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
StringToTextFile "a", BuildPath(work, "a.txt")
StringToTextFile "b", BuildPath(work, "b.txt")
StringToTextFile "c", BuildPath(work, "c.txt")
SetAttr BuildPath(work, "b.txt"), vbReadOnly

On Error Resume Next
DeleteFile BuildPath(work, "*.txt")             ' stops at the read-only file
Debug.Print Err.Number                          ' 70
Err.Clear
On Error GoTo 0
Debug.Print FileExists(BuildPath(work, "a.txt"))   ' False
Debug.Print FileExists(BuildPath(work, "c.txt"))   ' True

DeleteFile BuildPath(work, "*.txt"), force:=True
Debug.Print GetFilePaths(work).Count            ' 0
DeleteFolder work

DeleteFolder

Deletes a folder and everything in it.

Syntax: DeleteFolder ( folderPath [, force [, ignoreMissing ] ] )

folderPath
required A String naming the folder to delete. The last component can hold the wildcards * and ?, which match folders only.
force
optional A Boolean. True clears the read-only, hidden and system attributes as the contents are deleted. False (default) leaves them, and a read-only file stops the folder from being removed.
ignoreMissing
optional A Boolean. True does nothing when the path or the pattern matches no folder. False (default) raises error 76.

The contents are deleted first, and an item that cannot be deleted is skipped without an error. The folder itself is removed last; when it is not empty by then, the failure is reported.

Errors: 76 when no folder matches or a file is named; 75 when the folder is not empty because something in it could not be deleted, such as a read-only file when force is False (the message ends with the Windows code 145). The folder and the file stay. The Scripting Runtime raises error 70 in that case.

GetFilePaths

Returns the paths of the files in a folder.

Syntax: GetFilePaths ( folderPath [, pattern [, includeHidden [, includeSystem [, recursive ] ] ] ] ) As Collection

folderPath
required A String naming the folder.
pattern
optional A String, a file name that can hold the wildcards * and ?. Default: *. The pattern applies to the files of every folder that is searched, and not to the folders.
includeHidden
optional A Boolean. True includes hidden files. Default: False.
includeSystem
optional A Boolean. True includes system files. Default: False. A file that is both hidden and system needs both.
recursive
optional A Boolean. True also searches the subfolders, to any depth. Default: False.

Returns a Collection of String values, the full path of each file, starting at item 1. Folders are not in it. The order is the one in which Windows lists the folder. An empty result is an empty Collection. Hidden and system subfolders are searched only when includeHidden and includeSystem allow them.

Raises error 76 when folderPath is not a folder, and error 70 when a folder cannot be read. A junction or symbolic link in the tree is entered like a folder, so the files below its target are listed again under the link; see Junctions and symbolic links.

Unlike Folder.Files, the result leaves out hidden and system files unless they are asked for.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder BuildPath(work, "sub"), True
StringToTextFile "a", BuildPath(work, "a.txt")
StringToTextFile "b", BuildPath(work, "sub\b.txt")
StringToTextFile "c", BuildPath(work, "sub\c.md")

Debug.Print GetFilePaths(work, "*.txt").Count                    ' 1
Debug.Print GetFilePaths(work, "*.txt", recursive:=True).Count   ' 2

' A hidden file is left out unless it is asked for.
GetFile(BuildPath(work, "a.txt")).SetAttribute faHidden, True
Debug.Print GetFilePaths(work, "*.txt").Count                    ' 0
Debug.Print GetFilePaths(work, "*.txt", includeHidden:=True).Count   ' 1
Debug.Print GetFolder(work).Files.Count                          ' 1

DeleteFolder work

MoveFile

Moves one or more files.

Syntax: MoveFile ( source, destination ) As String

source
required A String naming the file to move. The last component can hold the wildcards * and ?, which match files only.
destination
required A String. An existing folder, or a path that ends in a backslash, is a folder: the file keeps its name in it. Any other path is the new full name of the file. A wildcard in it is error 5.

Returns the full path of the moved file. With a wildcard in source, it returns the full path of the destination folder, which must already exist.

A file is never replaced: when the destination file exists, error 58 is raised. A destination that is an existing folder gets the file with or without a backslash at the end. The Scripting Runtime raises error 58 when the folder has no backslash.

Errors: 53 when a wildcard matches no file, or matches only folders; 76 when the destination folder of a wildcard move does not exist; 58 when the destination file exists.

Note

A source without a wildcard that names a folder is moved too, with no error: MoveFile "C:\old", "C:\new" renames the folder. The Scripting Runtime raises error 53.

MoveFolder

Moves one or more folders.

Syntax: MoveFolder ( source, destination ) As String

source
required A String naming the folder to move. The last component can hold the wildcards * and ?, which match folders only.
destination
required A String. An existing folder, or a path that ends in a backslash, is a folder: the source is moved into it and keeps its name. Any other path is the new full name of the folder. A wildcard in it is error 5.

Returns the full path of the moved folder, or the full path of the destination folder when source holds a wildcard.

A destination that is an existing folder gets the source with or without a backslash at the end. The Scripting Runtime raises error 58 when the folder has no backslash.

Errors: 76 when source names no folder, or a wildcard matches no folder; 5 for a wildcard in destination.

Rename

Renames a file or a folder in place.

Syntax: Rename ( source, newName ) As String

source
required A String naming the file or folder.
newName
required A String, a bare name or a path that resolves to the folder that holds source. Wildcards are not allowed.

Returns the full path of the renamed item.

newName cannot move the item to another folder. A change of letter case alone is allowed.

Errors: 53 when source does not exist (for a folder as well as a file); 58 when newName is the name of another item in that folder; 5 for a wildcard, and for a newName that leads to another folder.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
StringToTextFile "x", BuildPath(work, "old.txt")

Dim newPath As String
newPath = Rename(BuildPath(work, "old.txt"), "new.txt")
Debug.Print GetFileName(newPath)                     ' new.txt
Debug.Print FileExists(BuildPath(work, "old.txt"))   ' False

DeleteFolder work

Current directory and special folders

GetCurrentDir

Returns the current directory of the process.

Syntax: GetCurrentDir ( ) As String

Returns the path without a trailing backslash, except for a drive root (C:\). It is the folder against which a relative path is resolved. After ChDir, GetCurrentDir returns the new directory; after SetCurrentDir, CurDir$ does.

GetSpecialFolder

Returns the path of a well-known Windows folder.

Syntax: GetSpecialFolder ( specialFolder ) As String

specialFolder
required A SpecialFolderConst member.

Returns the path without a trailing backslash. sfTemporaryFolder (and its FSO name TemporaryFolder) returns the value of the TEMP environment variable; every other member is asked from Windows by its known-folder identifier. Raises error 5 for a value that is not a member. A program built for 32 bits gets the Program Files (x86) folder for both sfProgramFiles and sfProgramFilesX86, and the System32 path for sfSystemFolder; sfSystemX86Folder is SysWOW64. The letter case of the result can differ from that of the Scripting Runtime: C:\WINDOWS against C:\Windows.

Note

Scripting.FileSystemObject returns a Folder object from GetSpecialFolder. This procedure returns the path as a String. Use GetFolder on the result to get the object.

Debug.Print StrComp(GetSpecialFolder(sfWindowsFolder), Environ$("windir"), vbTextCompare)   ' 0
Debug.Print GetSpecialFolder(TemporaryFolder) = Environ$("TEMP")                           ' True
Debug.Print FolderExists(GetSpecialFolder(sfLocalAppData))                                 ' True

SetCurrentDir

Sets the current directory of the process.

Syntax: SetCurrentDir ( folderPath )

folderPath
required A String naming an existing folder. Windows limits the path to 260 characters here.

Relative paths given to the procedures of the package, and to the file statements of VBA, are resolved against the new directory: after SetCurrentDir work, Open "x.txt" For Output creates the file in work.

Errors: 53 when the folder does not exist, 76 when the path names a file, and 75 when the path is longer than 260 characters.

File information

GetFileEncoding

Returns the text encoding of a file.

Syntax: GetFileEncoding ( filePath [, sampleBytes ] ) As TextEncoding

filePath
required A String naming the file.
sampleBytes
optional A Long, the number of bytes at the start of the file to examine. Default: 65536.

Returns a TextEncoding member. A negative value means that the file starts with a BOM. A file that is empty, or looks like binary data, returns encUnknown. The decision is taken in this order:

  1. A BOM at the start: UTF-8, UTF-16, UTF-32 (little or big endian), GB18030 and UTF-7 each have one.
  2. A pattern of zero bytes that points to UTF-16 or UTF-32.
  3. UTF-8, when the first 8,192 bytes are valid UTF-8. Plain ASCII is valid UTF-8, so it is reported as encUtf8, and so is ASCII text that holds a zero byte.
  4. Binary data, when the sample is not valid UTF-8 and holds a zero byte, or more than 2% control characters other than tab, line feed, carriage return and form feed. The second test is made only for a sample of 64 bytes or more.
  5. Otherwise, encSystemAnsi.

The result is an estimate, as every guess about the encoding of a text file is. A file in UTF-16, UTF-32 or UTF-8, with or without a BOM, is found right; so is a Latin-1 file when the system code page is Latin-1. Text in another code page without a BOM is not: GB18030 text with an accented letter is reported as encSystemAnsi, and UTF-7 or Big5 text that is pure ASCII as encUtf8. A sample that ends in the first byte of a multi-byte sequence is judged without that byte, so a Latin-1 file whose only accented letter is its last byte is reported as encUtf8. Pass the encoding to the procedure that reads the file when it is known.

Raises error 5 when the file does not exist; see Errors.

GetFileLineEnding

Returns the line-ending style of a text file.

Syntax: GetFileLineEnding ( filePath [, encoding ] ) As NewlineType

filePath
required A String naming the file.
encoding
optional A TextEncoding member. Default: encAutoDetect.

Reads the whole file and returns a NewlineType member: nlWindows (CR LF), nlUnix (LF) or nlMacintosh (CR) when the file uses one style, nlMixed when it uses more than one, and nlUnknown when it has no line ending. nlMixed and nlUnknown are both 0, so they cannot be told apart by their value.

Raises error 5 for a binary file, and error 7 for a file too large for one String (over 2 GB). It raises the same error as GetFileEncoding for a missing file.

GetFileType

Returns the description of the type of a file or folder.

Syntax: GetFileType ( filePath ) As String

filePath
required A String naming a file or folder.

Returns the type name that Windows Explorer shows, in the language of the system: Application for an .exe file, File folder for a folder, and for other files the description registered for the extension, or TXT File for a .txt file when none is registered. The Scripting Runtime’s File.Type and Folder.Type return the same strings. When the shell cannot give a name, including when the path does not exist, the result is the extension in uppercase and the word File (TXT File), or just File when there is no extension.

GetFileVersion

Returns the version of an executable file.

Syntax: GetFileVersion ( filePath [, source ] ) As String

filePath
required A String naming the file. A path longer than 260 characters gives an empty string.
source
optional A FileVersionSource member. Default: fvFixed.

Returns the binary version as four numbers separated by dots, such as 10.0.19041.7725, with fvFixed, the same string as the Scripting Runtime. fvFileString returns the FileVersion text that the author of the file wrote into it, and fvProductString the ProductVersion text; both return the binary version when the file has no such text. Returns an empty string when the file has no version resource, and when the file does not exist. The Scripting Runtime raises an error for a file that does not exist (the Windows code 0x80070002, as the number -2147024894).

Dim kernel As String
kernel = BuildPath(GetSpecialFolder(sfSystemFolder), "kernel32.dll")
Debug.Print Len(GetFileVersion(kernel)) > 0                  ' True
Debug.Print Len(GetFileVersion(kernel, fvFileString)) > 0    ' True

Objects

GetDrive

Returns a Drive object.

Syntax: GetDrive ( drivePath ) As Drive

drivePath
required A String that starts with a drive letter (C, C:, C:\, or a longer path on that drive), or the path of a network share (\\server\share, or a longer path).

Returns the drive, with its letter in uppercase. A path on a drive is reduced to the drive. Raises error 68 when the string is of none of those forms, and when a lettered drive does not exist. A network share is not checked until a property of the Drive needs it.

GetDrives

Returns a Drives collection of every drive.

Syntax: GetDrives ( ) As Drives

Returns the logical drives that Windows has, in the order of their letters. Check Drive.IsReady before reading the size of one. The collection is a snapshot, and a drive that appears later is not in it.

GetFile

Returns a File object for an existing file.

Syntax: GetFile ( filePath ) As File

filePath
required A String naming the file.

Returns the object for the full path of the file. Its Name has the letter case that the file system stores. Raises error 53 when the file does not exist, or when the path is a folder.

GetFolder

Returns a Folder object for an existing folder.

Syntax: GetFolder ( folderPath ) As Folder

folderPath
required A String naming the folder. A drive root is allowed.

Returns the object for the full path of the folder. Its Name has the letter case that the file system stores. Raises error 76 when the folder does not exist, or when the path is a file.

Whole files

ArrayToTextFile

Writes the elements of a String array to a text file, one per line.

Syntax: ArrayToTextFile ( lines(), filePath [, encoding [, lineEnding ] ] )

lines
required A String array. Its elements are joined with the line ending. No line ending follows the last element, so a final empty element is what makes the file end with one.
filePath
required A String naming the file. An existing file is replaced.
encoding
optional A TextEncoding member. Default: encUtf8. A BOM is written only for the members with Bom in their name. encAutoDetect is read as encUtf8.
lineEnding
optional A NewlineType member. Default: nlWindows. nlNoChange is read as nlWindows, because a line ending is needed to join the lines.

The file is written as WriteStream writes it, read-only files included; see the warning there. TextFileToArray reads the result back into the same array. An array that is not dimensioned writes an empty file.

Errors: 52 when the last component of filePath holds <, >, :, ", |, ?, * or a control character, and in version 1.1.1.0 a character above U+7FFF (see Errors); the errors of WriteStream.

MergeTextFiles

Joins two text files into one.

Syntax: MergeTextFiles ( firstFilePath, secondFilePath [, outputFilePath [, insertBlankLineBetween [, firstFileEncoding [, secondFileEncoding ] ] ] ] )

firstFilePath
required A String naming the file whose text comes first.
secondFilePath
required A String naming the file whose text follows.
outputFilePath
optional A String naming the result. Default: an empty string, which replaces firstFilePath. The result can also be either input file.
insertBlankLineBetween
optional A Boolean. True puts an empty line between the two texts. Default: False.
firstFileEncoding
optional A TextEncoding member for the first file. Default: encAutoDetect.
secondFileEncoding
optional A TextEncoding member for the second file. Default: encAutoDetect.

The result has the encoding of the first file, with its BOM if it has one, and the line ending of the first file; a first file with mixed line endings, or none, gives CR LF. The lines of the second file are written in that encoding and with that line ending: a UTF-16 file with a BOM followed by a UTF-8 file with LF line endings gives a UTF-16 file with a BOM and CR LF line endings.

Every line is written with a line ending, the last one too, so the result ends with a line ending even when the files did not.

When the result is one of the inputs, the new text is written to a file beside it and swapped in once it is complete, and the input stays as it was after an error. When it is a separate file and an error occurs, the part that was written stays.

Errors: 5 when the first file does not exist or either file is binary; 53 when the second file does not exist; 52 for an output name with a character above U+7FFF (see Errors).

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

Dim fileA As String, fileB As String, fileOut As String
fileA = BuildPath(work, "a.txt")
fileB = BuildPath(work, "b.txt")
fileOut = BuildPath(work, "all.txt")
StringToTextFile "a1" & vbCrLf & "a2", fileA
StringToTextFile "b1" & vbLf & "b2", fileB

MergeTextFiles fileA, fileB, fileOut, True
Debug.Print Replace(TextFileToString(fileOut), vbCrLf, "|")   ' a1|a2||b1|b2|

DeleteFolder work

NormalizeTextFile

Rewrites a text file in place with a chosen encoding and line ending.

Syntax: NormalizeTextFile ( filePath [, toEncoding [, toNewLine [, fromEncoding [, toAttributes [, skipIfUnchanged ] ] ] ] ] ) As Boolean

filePath
required A String naming the file.
toEncoding
optional A TextEncoding member for the new file. Default: encUtf8, with no BOM; a file that starts with a BOM loses it. encAutoDetect is read as encUtf8.
toNewLine
optional A NewlineType member. Default: nlWindows. nlNoChange keeps the line endings as they are.
fromEncoding
optional A TextEncoding member for the file as it is now. Default: encAutoDetect.
toAttributes
optional A FileAttribute combination to give the file. Only the settable attributes count. Default: faNoChange, which keeps the attributes of the file.
skipIfUnchanged
optional A Boolean. True (default) leaves the file alone when the text would be written back with exactly the bytes it has. False always writes it.

Returns True when the file was changed, a change of attributes alone included, and False when it was left as it was. A second call with the same arguments returns False.

A binary file is refused with error 5; this includes a file that fromEncoding names when it is not UTF-16 or UTF-32 and holds binary data. An empty file stays empty, or becomes a BOM alone when toEncoding has one. The new file is written beside the old one and swapped in, as WriteStream does.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

Dim path As String
path = BuildPath(work, "script.txt")
StringToTextFile "one" & vbLf & "two" & vbLf, path
Debug.Print GetFileLineEnding(path) = nlUnix       ' True
Debug.Print NormalizeTextFile(path)                ' True
Debug.Print GetFileLineEnding(path) = nlWindows    ' True
Debug.Print NormalizeTextFile(path)                ' False

' The attributes of the file are kept, or set when toAttributes is given.
SetAttr path, vbHidden
Debug.Print NormalizeTextFile(path, , nlUnix)                ' True
Debug.Print GetAttr(path)                                    ' 2
Debug.Print NormalizeTextFile(path, , nlUnix, , faReadOnly)  ' True
Debug.Print GetAttr(path)                                    ' 1
SetAttr path, vbNormal

' A binary file is refused.
Dim bin() As Byte
ReDim bin(0 To 2)
bin(0) = 233: bin(1) = 0: bin(2) = 97
WriteStream bin, BuildPath(work, "data.bin")
On Error Resume Next
NormalizeTextFile BuildPath(work, "data.bin")
Debug.Print Err.Number                                       ' 5
Err.Clear

DeleteFolder work, True

ReadStream

Reads a file into a byte array.

Syntax: ReadStream ( filePath, stream() [, maxBytesToRead ] )

filePath
required A String naming the file.
stream
required A Byte array that receives the bytes. It is dimensioned from 0.
maxBytesToRead
optional A Long. A value of 0 or more reads at most that many bytes from the start of the file. Default: -1, the whole file.

An empty file, and a maxBytesToRead of 0, leave stream as it was: an array that already has elements keeps them, and one that has none stays without. Test the array with IsArrayInitialized before indexing it.

Raises error 7 when the whole file is longer than 2,147,483,647 bytes; a head of any size can be read from a larger file. Raises error 5 (file not found!) when the file does not exist; see Errors.

StringToTextFile

Writes a string to a text file.

Syntax: StringToTextFile ( text, filePath [, encoding [, outLineEnding ] ] )

text
required A String with the text to write.
filePath
required A String naming the file. An existing file is replaced.
encoding
optional A TextEncoding member. Default: encUtf8. A BOM is written only for the members with Bom in their name. encAutoDetect is read as encUtf8.
outLineEnding
optional A NewlineType member. A style other than nlNoChange converts every line ending in text, CR LF, LF or CR, to it. Default: nlNoChange, which writes text as it is.

An empty text creates an empty file, or one that holds only the BOM. The file is written as WriteStream writes it, and an existing read-only file is replaced without an error; see the warning there.

For a code page with a limited character set, a character that the code page does not have is replaced by the substitute character of that code page, without an error: the Greek letter pi written with encLatin1 becomes the byte 63, a question mark. An unpaired surrogate in text raises error 5 when the encoding is UTF-8.

Errors: 52 when the last component of filePath holds <, >, :, ", |, ?, * or a control character, and in version 1.1.1.0 a character above U+7FFF (see Errors); the errors of WriteStream.

Dim work As String, path As String, b() As Byte
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
path = BuildPath(work, "t.txt")

StringToTextFile ChrW$(960), path, encLatin1
ReadStream path, b
Debug.Print b(0)                       ' 63

StringToTextFile "a" & vbCr & "b" & vbLf, path, , nlUnix
ReadStream path, b
Debug.Print UBound(b) + 1              ' 4

On Error Resume Next
StringToTextFile ChrW$(&HD800&) & "x", path, encUtf8
Debug.Print Err.Number                 ' 5
Err.Clear

DeleteFolder work

TextFileToArray

Reads a text file into an array of lines.

Syntax: TextFileToArray ( filePath [, encoding ] ) As String()

filePath
required A String naming the file.
encoding
optional A TextEncoding member. Default: encAutoDetect. A BOM in the file decides over it.

Returns a String array, dimensioned from 0, with one element per line. CR LF, LF and CR all end a line, also in one file. The line endings are not in the elements. A line ending at the end of the file gives a last, empty element. An empty file returns an array that is not dimensioned; test it with IsArrayInitialized. A BOM is removed.

Raises error 5 for a binary file when the encoding is detected, and the error of GetFileEncoding for a missing file.

Dim work As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

Dim path As String, lines() As String, back() As String
path = BuildPath(work, "lines.txt")
lines = Split("first,second,third", ",")
ArrayToTextFile lines, path, encUtf8, nlUnix
Debug.Print GetFileLineEnding(path) = nlUnix     ' True

back = TextFileToArray(path)
Debug.Print UBound(back) - LBound(back) + 1      ' 3
Debug.Print back(2)                              ' third

DeleteFolder work

TextFileToString

Reads a text file into a string.

Syntax: TextFileToString ( filePath [, encoding [, outLineEnding ] ] ) As String

filePath
required A String naming the file.
encoding
optional A TextEncoding member. Default: encAutoDetect, which finds the encoding as GetFileEncoding does. An explicit encoding is used as it stands, unless the file starts with a BOM, which decides over it. A BOM member (encUtf8Bom) for a file without a BOM reads the file with the same code page.
outLineEnding
optional A NewlineType member. A style other than nlNoChange converts every line ending in the result to it. Default: nlNoChange.

Returns the text, without the BOM. An empty file returns an empty string. Bytes that are not valid in the encoding are replaced by a substitute character, without an error.

Raises error 5 for a file that looks binary when the encoding is detected (an explicit encoding is not checked), error 7 for a file of more than 2 GB, and the error of GetFileEncoding for a missing file.

WriteStream

Writes a byte array to a file.

Syntax: WriteStream ( stream(), filePath )

stream
required A Byte array. An empty array, or one that is not dimensioned, creates an empty file.
filePath
required A String naming the file. An existing file is replaced.

The bytes are first written to a new file in the same folder, <name>.~XXXXXXXX.tmp, which is then swapped in for the target. A failure part-way therefore leaves the old file whole. The folder must allow a new file to be created in it.

Errors: an unspecified error (the number -2147467259) when the folder does not exist, and error 70 when Windows refuses; see Errors for the other Windows failures.

Dim work As String, path As String, ts As TextStream, b() As Byte, lines() As String
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
path = BuildPath(work, "protected.txt")
ReDim b(0 To 0)
b(0) = 65
lines = Split("a,b", ",")

StringToTextFile "old", path
SetAttr path, vbReadOnly
StringToTextFile "new", path                 ' no error
Debug.Print TextFileToString(path)           ' new
Debug.Print GetAttr(path) And vbReadOnly     ' 0

SetAttr path, vbReadOnly
ArrayToTextFile lines, path
Debug.Print GetAttr(path) And vbReadOnly     ' 0

SetAttr path, vbReadOnly
WriteStream b, path
Debug.Print GetAttr(path) And vbReadOnly     ' 0

SetAttr path, vbReadOnly
On Error Resume Next
Set ts = CreateTextFile(path)
Debug.Print Err.Number                       ' 70
Err.Clear
WriteStream b, BuildPath(work, "missing\x.bin")
Debug.Print Err.Number                       ' -2147467259
Err.Clear
On Error GoTo 0

DeleteFolder work, True

Text streams

CreateTextFile

Creates a text file and returns a TextStream open for writing.

Syntax: CreateTextFile ( filePath [, overwrite [, encoding [, lineEnding ] ] ] ) As TextStream

filePath
required A String naming the file.
overwrite
optional A Boolean. True (default) empties an existing file. False raises error 58 when the file exists.
encoding
optional A TextEncoding member. Default: encUtf8, without a BOM. A member with Bom in its name writes the BOM when the file is created. encAutoDetect is read as encUtf8.
lineEnding
optional A NewlineType member that WriteLine and WriteBlankLines use. Default: nlWindows. Anything that is not nlUnix or nlMacintosh is CR LF.

The file is written in place, with no swap file, and an existing read-only file raises error 70. The errors are those of OpenTextFile for ForWriting, and error 52 for a name that has <, >, ", |, ?, * or a control character, and in version 1.1.1.0 a character above U+7FFF (see Errors).

Important

The third argument of Scripting.FileSystemObject.CreateTextFile is a Boolean Unicode, and this procedure’s third argument is an encoding. A Boolean converts to a number: True is -1, which is encAutoDetect, and on writing that means UTF-8, not UTF-16. False is 0, encSystemAnsi. Code ported from the Scripting Runtime that passes True needs encUtf16 or encUtf16Bom here.

Dim work As String, ts As TextStream
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work

' In code written for the Scripting Runtime, the last True meant Unicode.
Set ts = CreateTextFile(BuildPath(work, "a.txt"), True, True)
Debug.Print ts.Encoding = encUtf8       ' True
ts.Close

Set ts = CreateTextFile(BuildPath(work, "b.txt"), True, encUtf16Bom)
Debug.Print ts.Encoding = encUtf16Bom   ' True
ts.Close

DeleteFolder work

GetStandardStream

Returns a TextStream for the standard input, output or error stream of the process.

Syntax: GetStandardStream ( standardStreamType [, unicode ] ) As TextStream

standardStreamType
required A StandardStreamTypes member.
unicode
optional A Boolean. True reads and writes UTF-16 text, without a BOM. False (default) uses the system ANSI code page.

Standard input can be read, and standard output and error can be written. The stream does not own the handle, and Close does not close it. Reading waits for the other end. Line endings written are CR LF. For these streams Encoding returns encSystemAnsi, also when unicode is True, and IsStreaming returns False.

OpenTextFile

Opens a text file and returns a TextStream.

Syntax: OpenTextFile ( filePath [, ioMode [, create [, encoding [, writeModeLineEnding ] ] ] ] ) As TextStream

filePath
required A String naming the file.
ioMode
optional An IOMode member. Default: ForReading.
create
optional A Boolean. True creates the file when it does not exist, for ForWriting and ForAppending. Default: False.
encoding
optional A TextEncoding member. Default: encAutoDetect. See below.
writeModeLineEnding
optional A NewlineType member that WriteLine and WriteBlankLines use. Default: nlWindows. Anything that is not nlUnix or nlMacintosh is CR LF.

What the mode does:

  • ForReading requires the file. The encoding is found from the start of the file: a BOM first, then encoding when it names one, then the same guess as GetFileEncoding. A file that looks binary is refused with error 5 when the encoding is detected. An empty file is reported as UTF-8.
  • ForWriting empties the file when it is opened, for an encoding that is written in pieces; a stream that holds the whole file (UTF-7) replaces the file when it is closed or flushed. encoding gives the encoding, and encAutoDetect means UTF-8. A BOM is written for a member with Bom in its name. While the stream is open, other streams can read the file, and cannot open it for writing or appending (error 70). A stream open for reading does not stop another from opening the file for writing.
  • ForAppending adds to the end. A file that exists keeps its encoding and BOM, found as for reading: encoding is used only when the file has no BOM, and is not checked against the text in the file, so a wrong one mixes encodings in the file. A BOM is not written again, and none is written to an existing file that is empty. The line ending for WriteLine is the one the first 64 KB of the file use, and writeModeLineEnding is used only for an empty file, a file without a line ending and a file with mixed ones. A file that does not exist is created like a new file under ForWriting, with the BOM of the encoding.

Errors: 53 when the file does not exist for ForReading, or for the other modes with create False; 76 when the folder does not exist; 52 for a name that is not valid when create is True; 5 for an unknown ioMode, and for a binary file as above; 70 when another stream has the file open for writing. The error has an empty Err.Source and the standard text of its number, File not found for 53, without the path.

Important

The fourth argument of Scripting.FileSystemObject.OpenTextFile is a Tristate Format, and this procedure’s is an encoding. TristateTrue is -1, which is encAutoDetect: on writing that means UTF-8, not UTF-16. The default also differs: a file opened for writing here is UTF-8 without a BOM, where the Scripting Runtime writes ANSI.

This sample appends to a file that has a BOM and LF line endings. The new line gets the line ending of the file, and no second BOM is written:

Dim work As String, path As String, ts As TextStream
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
path = BuildPath(work, "log.txt")
StringToTextFile "a" & vbLf & "b" & vbLf, path, encUtf8Bom

Set ts = OpenTextFile(path, ForAppending)
ts.WriteLine "c"
ts.Close

Debug.Print GetFileLineEnding(path) = nlUnix      ' True
Debug.Print GetFileEncoding(path) = encUtf8Bom    ' True
Debug.Print Len(TextFileToString(path))           ' 6

DeleteFolder work

Enumerations

The enumerations are declared in the module and are global: encUtf8, ForReading and the other members are used without a prefix. DriveTypeConst belongs to the Drive class.

TextEncoding

An encoding of text in a file. The value is a Windows code page. A negative value is the same code page with a byte-order mark (BOM): it is written when a file is created with it, and expected when a file is read with it. A code page that has no member is used by its number:

Dim work As String, path As String, b() As Byte
work = BuildPath(Environ$("TEMP"), GetTempName("fst", ""))
CreateFolder work
path = BuildPath(work, "sjis.txt")

' Shift-JIS is code page 932. Hiragana A, U+3042, is the two bytes 82 A0.
StringToTextFile ChrW$(&H3042&), path, 932
ReadStream path, b
Debug.Print Hex$(b(0)) & " " & Hex$(b(1))     ' 82 A0
Debug.Print AscW(TextFileToString(path, 932))  ' 12354

DeleteFolder work
Member Value Meaning
encUnknown -1 As a result: the encoding could not be found (the file is empty or binary). Same value as encAutoDetect.
encAutoDetect -1 As an argument for reading: find the encoding. As an argument for writing: encUtf8.
encSystemAnsi 0 The ANSI code page of the system.
encGB2312 936 Simplified Chinese, GBK.
encBig5 950 Traditional Chinese.
encUtf16 1200 UTF-16, little endian, no BOM.
encUtf16Be 1201 UTF-16, big endian, no BOM.
encUtf32 12000 UTF-32, little endian, no BOM.
encUtf32Be 12001 UTF-32, big endian, no BOM.
encUsAscii 20127 US-ASCII.
encLatin1 28591 ISO 8859-1.
encLatin9 28605 ISO 8859-15.
encGB18030 54936 GB18030, no BOM.
encUtf7 65000 UTF-7, no BOM.
encUtf8 65001 UTF-8, no BOM.
encUtf8Bom -65001 UTF-8 with the BOM EF BB BF.
encUtf16Bom -1200 UTF-16, little endian, with the BOM FF FE.
encUtf16BeBom -1201 UTF-16, big endian, with the BOM FE FF.
encUtf32Bom -12000 UTF-32, little endian, with the BOM FF FE 00 00.
encUtf32BeBom -12001 UTF-32, big endian, with the BOM 00 00 FE FF.
encUtf7Bom -65000 UTF-7 with the signature +/v8-.
encGB18030Bom -54936 GB18030 with the BOM 84 31 95 33.

Only these seven negative members have a BOM. A BOM member given for reading a file that has no BOM reads it with the code page alone.

NewlineType

A line-ending style.

Member Value Meaning
nlUnknown 0 As a result: the text has no line ending.
nlMixed 0 As a result: the text has more than one style.
nlNoChange 0 As an argument: leave the line endings as they are.
nlWindows 1 Carriage return and line feed (vbCrLf).
nlUnix 2 Line feed (vbLf).
nlMacintosh 3 Carriage return (vbCr).

IOMode

How OpenTextFile opens a file. The values are those of the Scripting Runtime.

Member Value Meaning
ForReading 1 Read. The file must exist.
ForWriting 2 Write, from an empty file.
ForAppending 8 Write at the end of the file.

SpecialFolderConst

A well-known folder, for GetSpecialFolder. The first three members have the values of the Scripting Runtime, and WindowsFolder, SystemFolder and TemporaryFolder are names for them that match it. The rest are known folders of Windows.

Member Value Folder
sfWindowsFolder, WindowsFolder 0 The Windows folder.
sfSystemFolder, SystemFolder 1 The System32 folder.
sfTemporaryFolder, TemporaryFolder 2 The folder named by the TEMP environment variable.
sfSystemX86Folder 3 The 32-bit system folder (SysWOW64 on 64-bit Windows).
sfProgramFiles 4 Program Files.
sfProgramFilesX86 5 Program Files (x86).
sfProgramData 6 ProgramData.
sfUserProfile 7 The profile folder of the current user.
sfDesktop 8 The desktop of the current user.
sfDocuments 9 Documents of the current user.
sfDownloads 10 Downloads of the current user.
sfPictures 11 Pictures of the current user.
sfMusic 12 Music of the current user.
sfVideos 13 Videos of the current user.
sfLocalAppData 14 Local application data (AppData\Local).
sfRoamingAppData 15 Roaming application data (AppData\Roaming).
sfPublicDesktop 16 The desktop shared by all users.
sfPublicDocuments 17 Documents shared by all users.
sfPublicDownloads 18 Downloads shared by all users.
sfPublicPictures 19 Pictures shared by all users.
sfPublicMusic 20 Music shared by all users.
sfPublicVideos 21 Videos shared by all users.
sfFonts 22 Fonts.
sfStartup 23 The Startup folder of the current user.
sfCommonStartup 24 The Startup folder of all users.

FileAttribute

The attributes of a file or folder, for File.Attributes, Folder.Attributes and NormalizeTextFile. The values are those of Windows. Combine them with Or.

Reading an attribute set returns every attribute that the file system reports. Writing applies only the settable ones, listed first; the others are dropped without an error. faNormal means no attributes, and it wins over any other member it is combined with: faNormal Or faReadOnly clears every settable attribute. The FSO values Volume (8) and Alias (1024) are not members: the label of a volume is Drive.VolumeName, and an alias is faReparsePoint.

Member Value Meaning
faNoChange -1 As an argument: keep the attributes.
faNormal, Normal 128 No attributes. Settable.
faReadOnly, ReadOnly 1 Read-only. Settable.
faHidden, Hidden 2 Hidden. Settable.
faSystem, System 4 System file. Settable.
faArchive, Archive 32 Changed since the last backup. Settable.
faTemporary 256 Temporary file. Settable.
faNotContentIndexed 8192 Not indexed by the content indexing service. Settable.
faDirectory, Directory 16 A folder.
faCompressed, Compressed 2048 Compressed.
faEncrypted 16384 Encrypted.
faReparsePoint 1024 A reparse point: a junction, a symbolic link or a cloud placeholder.
faSparseFile 512 A sparse file.
faOffline 4096 The content is not available locally.
faIntegrityStream 32768 A checksummed stream (NTFS, ReFS).
faVirtual 65536 Reserved by Windows.
faNoScrubData 131072 Excluded from the integrity scrubber.
faEA 262144 Has extended attributes. Same value as faRecallOnOpen.
faRecallOnOpen 262144 A cloud file recalled when it is opened.
faPinned 524288 A cloud file kept on this computer.
faUnpinned 1048576 A cloud file that may be removed from this computer.
faRecallOnDataAccess 4194304 A cloud file recalled when its data is read.
faStrictlySequential 536870912 Meant for sequential access.

FileVersionSource

Which version a file reports, for GetFileVersion.

Member Value Meaning
fvFixed 0 The binary version of the file, four numbers.
fvFileString 1 The FileVersion text of the file.
fvProductString 2 The ProductVersion text of the file.

StandardStreamTypes

A standard stream of the process, for GetStandardStream. The values are those of the Scripting Runtime.

Member Value Meaning
StdIn 0 Standard input.
StdOut 1 Standard output.
StdErr 2 Standard error.

See Also

  • FileSystemObject class – the same procedures as the members of a COM object
  • File class – a file, returned by GetFile
  • Folder class – a folder, returned by GetFolder
  • Drive class – a drive, returned by GetDrive
  • TextStream class – the text stream returned by OpenTextFile and CreateTextFile
  • FileCopy function – the VBA statement that copies one file
  • Kill function – the VBA statement that deletes files
  • Open statement – the VBA statement that opens a file for input and output