Moving Files to the Trash

August 3rd, 2008 by Joe Ranieri

On 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.


COMMENTS

Leave a Reply