Lazarus

Programming => Operating Systems => macOS / Mac OS X => Topic started by: han on September 26, 2022, 06:15:15 pm

Title: Movefile for Darwin/macOS
Post by: han on September 26, 2022, 06:15:15 pm
For Windows I can move files to an other directory as follows:

Code: [Select]
            err:=movefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2)));
or
            err:=renamefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2)));//rename is the same as movefile



In Linux I can also movefiles by renamefile

Code: [Select]
            err:=renamefile(pchar(filename2),pchar(thepath+'/'+extractfilename(filename2)));//rename is the same as movefile

But the renamefile solution to move a file doesn't work for macOS. How can I move a file in macOS?

Han

Title: Re: Movefile for Darwin/macOS
Post by: marcov on September 26, 2022, 06:24:17 pm
(note that rename instead of move only works for moves within one filesystem)
Title: Re: Movefile for Darwin/macOS
Post by: han on September 26, 2022, 06:39:29 pm
(note that rename instead of move only works for moves within one filesystem)

For Windows I can rename files from my harddisk to an USB stick. Is there any other limitation?

Probably for macOS I can execute a command-line but hopefully there is a more elegant solution.
Title: Re: Movefile for Darwin/macOS
Post by: dsiders on September 26, 2022, 06:42:12 pm
For Windows I can move files to an other directory as follows:

Code: [Select]
            err:=movefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2)));
or
            err:=renamefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2)));//rename is the same as movefile



In Linux I can also movefiles by renamefile

Code: [Select]
            err:=renamefile(pchar(filename2),pchar(thepath+'/'+extractfilename(filename2)));//rename is the same as movefile

But the renamefile solution to move a file doesn't work for macOS. How can I move a file in macOS?

Han

If you look at the source, the arguments are defined as RawByteString in the macOS RTL. Think different. :)
Title: Re: Movefile for Darwin/macOS
Post by: han on September 26, 2022, 07:24:04 pm
Think different? That is a Mac slogan. Thinking out of the box maybe. The pchar() should not be there for renamefile, only for movefile. But it still doesn't work for macOS. I don't see a solution.

Code: [Select]
err:=renamefile(filename2,thepath+'/'+extractfilename(filename2));
Title: Re: Movefile for Darwin/macOS
Post by: Jonas Maebe on September 26, 2022, 10:35:48 pm
See the description of https://www.freepascal.org/docs-html/rtl/sysutils/renamefile.html . It is explicitly documented as not supporting moving a file across different disks/partitions on Unix platforms (like Darwin/macOS). In that case, you have to copy the file and then delete the original one. If you want, you can use https://wiki.freepascal.org/CopyFile from Lazarus for this (I don't think its fileutil unit depends on the LCL).
Title: Re: Movefile for Darwin/macOS
Post by: han on September 27, 2022, 09:44:08 am
Okay now it is all clear.  Contradicting with previous finding, in macOS renamefile works in one partition. I missed then due to an other fault I did not notice due to a problem with the debugger. The copyfile flag cffPreserveTime makes an elegant solution possible for more then one partition:

Movefile for more then one partition:
Code: [Select]
  {$ifdef mswindows}
  // succ:=movefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2))); 
   succ:=renamefile(filename2,thepath+'\'+extractfilename(filename2));//rename works the same as movefile
  {$else} {Linux, Darwin}
  succ:=copyfile(filename2,thepath+'/'+extractfilename(filename2), [cffPreserveTime]); //works for more then one partition.
  if succ then
   succ:=deletefile(filename2);
  {$endif}

For Windows I don't see a difference between movefile and renamefile so you can use both.

Movefile for a single partition:
Code: [Select]
  {$ifdef mswindows}
  // succ:=movefile(pchar(filename2),pchar(thepath+'\'+extractfilename(filename2))); 
   succ:=renamefile(filename2,thepath+'\'+extractfilename(filename2))
  {$else} {Linux, Darwin}
   succ:=renamefile(filename2,thepath+'/'+extractfilename(filename2));
  {$endif}

TinyPortal © 2005-2018