Directory NSFileWrapper does not update fileWrappers after removeItem

Hi, I encounter unexpected behavior from the FileWrapper updates that occurs when I remove file using FileManager.removeItem

If I first remove a file from the directory, then create NSFileWrapper instance, I get unexpected values from calls to matchesContents(of:)

import Foundation

let copyURL = URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test/COPY.png")

// THIS OPERATION BREAKS IT. REMOVE IT TO WORK AS EXPECTED
try! FileManager().removeItem(at: copyURL) 

let dirURL = URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test")

let fw = try FileWrapper(url: dirURL)
fw.fileWrappers                 // ["IMG_0736.png"]

try FileManager.default.copyItem(at: URL(filePath: "/Users/marcinkrzyzanowski/Downloads/filewrappertest.test/IMG_0736.png"), to: copyURL)

fw.fileWrappers                // ["IMG_0736.png"]
fw.matchesContents(of: dirURL) // true (expected: false)

try fw.read(from: dirURL)

fw.fileWrappers!               // ["COPY.png", "IMG_0736.png"]
fw.matchesContents(of: dirURL) // true

I don't understand why the "FileManager.removeItem" affects the NSFileWrapper behavior in such a way. It does not change even when I add a delay after removeItem. Any idea?

Hi, I encounter unexpected behavior from the FileWrapper updates that occurs when I remove file using FileManager.removeItem

If I first remove a file from the directory, then create NSFileWrapper instance, I get unexpected values from calls to matchesContents(of:)

First off, making sure my understanding is correct, what you're seeing is the following:

Working case:

  • Make a file wrapper for the directory
  • Add a file to the directory wrapper
  • Call matchesContents(of:)

Result: false (expected)

Working case:

  • Delete file from inside wrapper directory
  • Make a file wrapper for the directory
  • Add a file to the directory wrapper
  • Call matchesContents(of:)

Result: true (NOT expected)

Assuming that's the case, then I think what's going on here is that, because the wrapper has not yet been read, the initial "matchesContents(of:)" is relying on modification dates. That works fine in the first case because the original data (read at init) is at some point in the "distant" past. However, in the second case the first delete means that the date modification date is now "close enough" date isn't considered to have "changed".

Note that file system time stamp granularity can be quite large. HFS+ uses 1s and FAT32 uses 2s. APFS time stamps are much more granular but there are intermediate layers in the system that could have made that invisible to NSFileWrapper. More to the point, the time gap between the two operations is going to be quite small.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Directory NSFileWrapper does not update fileWrappers after removeItem
 
 
Q