FolderItem

From Xojo Documentation

Class (inherits from Object)

FolderItem class objects represent files, applications, or folders. They are created by calling a method such as GetFolderItem or via the Parent or Item properties of other FolderItem objects.

Properties
Count fa-lock-32.png IsReadable fa-lock-32.png Parent fa-lock-32.png
CreationDateTime IsWriteable fa-lock-32.png Permissions
DisplayName fa-lock-32.png Length fa-lock-32.png ShellPath fa-lock-32.png
Exists fa-lock-32.png Locked Type fa-lock-32.png
ExtensionVisible ModificationDateTime URLPath fa-lock-32.png
Group Name VirtualVolume
IsAlias fa-lock-32.png NativePath fa-lock-32.png Visible
IsFolder fa-lock-32.png Owner


Methods
Child CreateAsFolder MoveFileTo
ChildAt CreateVirtualVolume OpenAsVirtualVolume
Children FromSaveInfo Remove
CopyFileTo Launch SaveInfo
Enumerations
PathModes SaveInfoModes
Shared Properties
DriveCount fa-lock-32.png LastDriveIndex fa-lock-32.png
Shared Methods
DriveAt ShowSaveFileDialog
FromSaveInfo ShowSelectFolderDialog
ShowOpenFileDialog TemporaryFile


Constructors

Constructor(f as FolderItem)


Constructor(path as String, pathMode as FolderItem.PathModes, followAlias as Boolean = true)



Notes

Case Sensitivity

Be aware that file systems on macOS and Windows are generally not case-sensitive, while file systems on Linux usually are case-sensitive. This means that if you are creating apps to deploy on Linux (including web apps deployed to Linux servers), you need to ensure that your filenames correctly match case. If you do not, you may find that files cannot be found when your app is running on Linux.

Performance Considerations

Avoid invoking functions such as Count, Child and IgnoreAlias multiple times for the same target because these functions are time-intensive (especially on macOS).

If you walk directory contents, follow these rules:

  • Always iterate forward, starting at index 0 and ending with the index that matches the folder's Count. If you iterate backward, it may get very slow if the directory contains a few hundred or even more items.
  • If you want to recurse into subfolders, do not go depth-first. Instead, first collect all items into an array of FolderItems, then walk the array items and enter any folders you encounter.
  • To delete items from a folder, follow the above rules as well. Do not be tempted to walk the directory items backwards (from Count downto 0), even if you see many recommendations for doing so. The proper way is to first collect all items in a loop into an array, then walk the array and delete the items accordingly.

Specifying Pathnames

Use the Volume function, the Parent property of the FolderItem class, and the Child method of the FolderItem class to specify pathnames. The Volume function returns a reference to any volume on the user's computer. Pass it a number that indicates the desired volume. Zero is the boot volume. You can get the number of volumes with the VolumeCount function. For example, to get a FolderItem for Microsoft Word in the Program Files folder on the boot volume, you can use the following line of code (The line continuation keyword, [[_]], is used to split the line into two printed lines).

Var f As FolderItem
f = Volume(0).Child("Program Files").Child("Microsoft Office"). _
Child("OFFICE11").Child("WINWORD.EXE")

The Folderitem.Constructor function can be used to get a FolderItem for an item in the current folder. Simply pass it the name of the item. For example, the following returns a FolderItem for the folder "MyTemplates" in the current folder:

Var f As new FolderItem("MyTemplates")

If the document or folder does not exist, the Exists property of the FolderItem is False.

If you pass the empty string to FolderItem.Constructor, it returns the FolderItem for the folder that contains the application.

Var f As new FolderItem("")

The Parent property of the FolderItem class enables you to navigate one level up in the hierarchy. For example, the following gives you the FolderItem for the folder that contains the folder that contains the application:

Var f As new FolderItem("").Parent

Remember, macOS is based on BSD Unix which uses "/" as the separator.

Shell Paths and Regular Paths

If you pass the optional parameter for path, you can also pass an optional second parameter indicating whether the path is a ShellPath, a "regular" path, or a path in the form of a URL. FolderItem.PathModes has three modes that you use to indicate this, Native, Shell, and URL. For example:

Var f As FolderItem
f = New FolderItem("/home/shr/mytextdoc.txt",[folderItem.pathModes.Shell)

You cannot pass a non-absolute Shell path. Attempting to do so will result in an UnsupportedFormatException.

If you use FolderItem.PathModes.URL, the URL must begin with "file:///".

fa-exclamation-circle-32.png
On MacOS with Xojo 2019r1 or earlier, constructing FolderItems with a URL where the filename included a ? character would cause that character and any that followed to be stripped. This is no longer the case in Xojo 2019r2 or greater and is now consistent across all platforms.

You can also create a FolderItem without passing any parameters. It works the same as passing an empty text string.

Aliases

If a FolderItem is actually an alias to a FolderItem, the alias is automatically resolved when the FolderItem is accessed unless you use IgnoreAlias which returns the item itself, even if it is an alias. Use the Alias property to determine whether the FolderItem is an alias.

Examples

This example puts the names of all the items on the Desktop that are stored on the boot volume into ListBox1.

Var desktopFolder As FolderItem = SpecialFolder.Desktop
If desktopFolder Is Nil Then
Return
End If

For Each file as Folderitem in DesktopFolder.Children
If file <> Nil Then
ListBox1.AddRow(file.Name)
End If
Next

This example uses MoveFileTo. The source file will be deleted and moved into the destination folder. The destination is specified as the root of Volume 0. The name of the destination file OPis the same as the source. Notice that it checks that the source file exists and the destination FolderItem is not Nil.

Var f, g As FolderItem

f = Folderitem.ShowOpenFileDialog(FileTypes1.Text)
If f <> Nil Then // if the user didn't cancel..
If f.Exists Then // if it is a valid file...
g = Volume(0).Child(f.Name)
If g <> Nil Then
f.MoveFileTo(g)
MessageBox("success!")
End If
End If
Else
MessageBox("File not found!")
End If

The following example creates a text file, changes the Creator from the default creator of "R*ch" to "ttxt", and writes some data to the file.

Var f As FolderItem
Var stream As TextOutputStream
f = Folderitem.ShowSaveFileDialog(FileTypes1.Text, "Daily Planet Staff.txt")
If f <> Nil then
stream = TextOutputStream.Create(f)
f.MacCreator = "ttxt"
Stream.WriteLine("Perry White")
Stream.WriteLine("Lois Lane")
Stream.WriteLine("Jimmy Olsen")
Stream.Close
End If

This example displays the Open File dialog box and lets the user choose a JPEG file that is then assigned to the Backdrop property of a Canvas control.

Var f As FolderItem = Folderitem.ShowOpenFileDialog(FileTypes1.Jpeg)
If f Is Nil Then
// user cancelled
Return
End If

Try
Canvas1.Backdrop = Picture.Open(f)
Catch e As IOException
// unable to open picture
End Try

This example displays an open-file dialog box that lets the user select a movie. The movie is then copied into the Movie property of a MoviePlayer control.

Var f As FolderItem = Folderitem.ShowOpenFileDialog(FileTypes1.Movie)
If f <> Nil Then
Try
MoviePlayer1.Movie.Open(f)
Catch e As IOException
// Unable to open movie
End Try
Else
// user cancelled
End If

This example copies all the files in a particular folder. The following code is a button's Pressed:

Var origin, destination As FolderItem
origin = Folderitem.ShowSelectFolderDialog
If origin <> Nil Then
destination = Folderitem.ShowSelectFolderDialog
If destination <> Nil Then
CopyFileOrFolder(origin, destination) // See below
MessageBox("Copy complete!")
End If
End If

The CopyFileOrFolder method is as follows:

Sub CopyFileOrFolder(source As FolderItem, destination As FolderItem)
Var newFolder As FolderItem

If source.IsFolder Then // it's a folder
newFolder = destination.Child(source.Name)
newFolder.CreateAsFolder
For Each file As Folderitem in source.Children //go through each item
If file.isFolder Then
// it's a folder
CopyFileOrFolder(file, newFolder) // recursively call this routine passing it the folder
Else
file.CopyFileTo(newFolder) // it's a file so copy it
End If
Next
Else // it's not a folder
source.CopyFileTo(destination)
End If
End Sub

Using FromSaveInfo:

Var f, g As FolderItem
f = New FolderItem
g = f.FromSaveInfo(f.SaveInfo(Volume(0).Child("Documents"), 0))
If g <> Nil Then
Label2.Value = g.AbsolutePath
Else
MessageBox("FolderItem does not exist!")
End If

See Also

Volume, VolumeCount functions; BinaryStream, FolderItemDialog, OpenDialog, SaveAsDialog, SelectFolderDialog, SpecialFolder, TextInputStream, TextOutputStream classes