Moving Files to the Trash
August 3rd, 2008On the REALbasic forums, a question involving moving files to the trash came up. The approach taken was to use myFolderItem.moveFileTo(SpecialFolder.trash), but this has some problems. First off, this will move the file across different volumes, resulting in extremely long wait times (and application hangs) for large files. Secondly, it will fail if there is already a file of the same name in the Trash.
To make this task easier, Apple introduced the FSMoveObjectToTrashSync function in Leopard. Prior to Leopard, you had the options of rolling your own (and getting it wrong in subtle ways) or using NSWorkspace’s performFileOperation:source:destination:files:tag:.
To use FSMoveObjectToTrashSync, we’ll need to convert the FolderItem into an FSRef. This is actually fairly trivial, CoreFoundation will take care of all of the messy details for you:
Function GetFSRef(f as FolderItem) as MemoryBlock declare function CFURLCreateWithString lib "CoreFoundation" ( allocator as ptr, _ urlString as CFStringRef, baseURL as ptr ) as ptr declare function CFURLGetFSRef lib "CoreFoundation" ( url as ptr, fsRef as ptr ) _ as boolean declare sub CFRelease lib "CoreFoundation" ( obj as ptr ) dim result as new MemoryBlock( 80 ) dim url as ptr = CFURLCreateWithString( nil, f.urlPath, nil ) call CFURLGetFSRef( url, result ) CFRelease( url ) return result End Function
Then we can just call FSMoveObjectToTrashSync:
Sub MoveToTrash(f as FolderItem) declare function FSMoveObjectToTrashSync lib "CoreServices" ( source as ptr, _ target as ptr, options as integer ) as integer const kFSFileOperationDefaultOptions = 0 dim ref as MemoryBlock = getFSRef( f ) call FSMoveObjectToTrashSync( ref, nil, kFSFileOperationDefaultOptions ) End Sub
Note that in both code snippets, error handling is left as an exercise for the reader.