I'm writing a function where a directory and its descendants are scanned to produce a list of files. The function is part of a class, FileScanner. Here's a simplified version of the function:
func scanFolder(_ folderURL: URL) async {
// Set up configuration for directory search, varies based on need to search sub directories
let resourceKeysArray: [URLResourceKey] = [.nameKey, .isDirectoryKey, .fileResourceTypeKey, .creationDateKey, .contentModificationDateKey, .contentTypeKey]
let resourceKeysSet = Set<URLResourceKey>(resourceKeysArray)
let options = FileManager.DirectoryEnumerationOptions(arrayLiteral: [.skipsHiddenFiles, .skipsPackageDescendants])
if let enumerator = FileManager.default.enumerator(at: folderURL, includingPropertiesForKeys: resourceKeysArray, options: options) {
await folderScanStatus.markRunning()
while
await !folderScanStatus.cancelled,
let fileURL = enumerator.nextObject() as? URL
{
print("\(id) found \(fileURL.path)") // Logging for debug purposes
foundFiles.append(fileURL)
}
}
}
The code is async, as it has to call some async functions (I've left a couple in for illustration.)
The user can have multiple scans in process simultaneously. For each one a new FileScanner is created, and de-inited once the scan has completed - the results are copied across elsewhere. scanFolder is called from within a Task:
Task { await scanFolder(someURL) }
I am finding that if two of these processes run at once, they can actually interfere with each other - i.e. one can scan the directory of the other.
I added some logging to highlight the issue. The log line shows the ID of the scanner, and the file it has found. In this run there were two scanners:
- EDF43558-608E-47A4-81E5-97B9707B1D0F, scanning /Volumes/Back-up A/
- 982EC712-D79E-4785-A1BA-3B53F85967F0, scanning /Users/TEST/
And here's some extracts from the log showing them working as expected:
982EC712-D79E-4785-A1BA-3B53F85967F0 found /Users/TEST/Files/R_24_04-04.txt
EDF43558-608E-47A4-81E5-97B9707B1D0F found /Volumes/Back-up A/180704f01.txt
And here's an example showing Scanner 982EC712-D79E-4785-A1BA-3B53F85967F0 finding a file that the other one also picked up:
982EC712-D79E-4785-A1BA-3B53F85967F0 found /Volumes/Back-up A/19839f92.txt
:
EDF43558-608E-47A4-81E5-97B9707B1D0F found /Volumes/Back-up A/19839f92.txt
Any ideas why this is happening? I was under the impression FileManager was thread safe?