listDirectory method
Lists the contents of the directory at the given path.
Implementation
@override
Future<List<FileSystemEntity>> listDirectory(String path) async {
try {
final resolvedPhysicalPath = resolvePath(path);
// Special Case: Listing the virtual root ('/').
// We don't list a physical directory. Instead, we list the *keys*
// of the directory mappings, representing the top-level virtual folders.
if (resolvedPhysicalPath == rootDirectory) {
// Return Directory objects where the path is just the mapping key (e.g., 'docs', 'pics').
// This represents the virtual entries available at the root.
// The FTP client will see these as directories.
return directoryMappings.keys
.map((key) =>
Directory(key)) // Represent virtual entry using its key.
.toList();
}
// Standard Case: Listing a directory within a mapping.
// The resolved path is a physical directory path.
final dir = Directory(resolvedPhysicalPath);
if (!await dir.exists()) {
throw FileSystemException(
"Directory not found: '$path' (resolved to '$resolvedPhysicalPath')",
path);
}
// Get the physical entities within the directory.
// NOTE: listSync() can block on large directories. Consider async list() if performance is critical.
final physicalEntities = dir.listSync();
final virtualEntities = <FileSystemEntity>[];
// Convert physical entities back to virtual representations.
for (var entity in physicalEntities) {
// Get the virtual path corresponding to the physical entity's path.
final virtualPath = _getVirtualPath(entity.path);
// Create a new FileSystemEntity (File or Directory) using the *virtual* path.
// This is what the FTP client will see.
if (entity is Directory) {
virtualEntities.add(Directory(virtualPath));
} else if (entity is File) {
virtualEntities.add(File(virtualPath));
}
// Ignore other types like Links for simplicity, or handle as needed.
}
return virtualEntities;
} catch (e) {
if (e is FileSystemException) {
rethrow;
}
throw FileSystemException(
"Failed to list directory '$path': ${e.toString()}", path);
}
}