Thread overview
std.file.copy isn't a true copy operation
Feb 24, 2005
Stewart Gordon
Feb 28, 2005
Matthew
Mar 01, 2005
Nick
Mar 01, 2005
Stewart Gordon
Mar 01, 2005
Russ Lewis
February 24, 2005
Most of the functions in std.file are written to use OS API functions where applicable.  However, for some obscure reason, copy goes out of its way not to use any such thing, but instead it loads the file and re-saves it.

I knew of a program that transferred movie files like this, though probably doing it in chunks rather than all at once.  The consequence was that it was rather slow, and screwed up the timestamps.

OTOH, a file copy operation (on MS-DOS and Windows at least) preserves timestamps and certain attributes, and (also unlike std.file.copy) will work fine on files of arbitrary size (within obvious constraints).

Doing a file copy on Win32 is as straightforward as the other various file operations.  Here it is:

----------
void copy(char[] from, char[] to) {
    BOOL result;

    if (useWfuncs) {
        result = CopyFileW(std.utf.toUTF16z(from), std.utf.toUTF16z(to),
          false);
    } else {
        result = CopyFileA(toMBSz(from), toMBSz(to), false);
    }
    if (!result) {
        throw new FileException(to, GetLastErrror());
    }
}
----------

This should be put in version(Win32), and the current implementation moved into the version(linux) block.

The CopyFile functions'll also have to be put in std.c.windows.windows:

----------
BOOL CopyFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName,
  BOOL bFailIfExists);
BOOL CopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName,
  BOOL bFailIfExists);
----------

I imagine that there's also an OS call on Unix platforms to do it, though I haven't as yet found it.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
February 28, 2005
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:cvkeme$rps$1@digitaldaemon.com...
> Most of the functions in std.file are written to use OS API functions where applicable.  However, for some obscure reason, copy goes out of its way not to use any such thing, but instead it loads the file and re-saves it.
>
> I knew of a program that transferred movie files like this, though probably doing it in chunks rather than all at once.  The consequence was that it was rather slow, and screwed up the timestamps.
>
> OTOH, a file copy operation (on MS-DOS and Windows at least) preserves timestamps and certain attributes, and (also unlike std.file.copy) will work fine on files of arbitrary size (within obvious constraints).
>
> Doing a file copy on Win32 is as straightforward as the other various file operations.  Here it is:
>
> ----------
> void copy(char[] from, char[] to) {
>     BOOL result;
>
>     if (useWfuncs) {
>         result = CopyFileW(std.utf.toUTF16z(from),
> std.utf.toUTF16z(to),
>           false);
>     } else {
>         result = CopyFileA(toMBSz(from), toMBSz(to), false);
>     }
>     if (!result) {
>         throw new FileException(to, GetLastErrror());
>     }
> }
> ----------
>
> This should be put in version(Win32), and the current implementation moved into the version(linux) block.
>
> The CopyFile functions'll also have to be put in std.c.windows.windows:
>
> ----------
> BOOL CopyFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName,
>   BOOL bFailIfExists);
> BOOL CopyFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName,
>   BOOL bFailIfExists);
> ----------
>
> I imagine that there's also an OS call on Unix platforms to do it, though I haven't as yet found it.

There may be some on individual flavours, but I'm moderately sure it's not a standard UNIX thing.

I totally agree about the timestamps, etc.



March 01, 2005
In article <d0064p$rgm$2@digitaldaemon.com>, Matthew says...
>>
>> I imagine that there's also an OS call on Unix platforms to do it, though I haven't as yet found it.
>
>There may be some on individual flavours, but I'm moderately sure it's not a standard UNIX thing.

I'm pretty sure too. For fun I downloaded and checked the source for 'cp' from gnu.org. It looks mighty long and complicated, not as small and elegant a program as you would think.

Nick


March 01, 2005
Nick wrote:
> In article <d0064p$rgm$2@digitaldaemon.com>, Matthew says...
> 
>>> I imagine that there's also an OS call on Unix platforms to do it, though I haven't as yet found it.
>>
>> There may be some on individual flavours, but I'm moderately sure it's not a standard UNIX thing.
> 
> I'm pretty sure too. For fun I downloaded and checked the source for 'cp' from gnu.org.

Any recollection of the exact URL?  I can't seem to find it with a quick look.

> It looks mighty long and complicated, not as small and elegant a program as you would think.

That suggests that a file copy operation on Unix essentially means running this tool.  And it seems that on at least some Unices, copying doesn't preserve timestamps.  When I try from Mac OS X, there seems to be a grey area - copying from Finder preserves the timestamp, but cp from the shell doesn't.  (Does this mean that the correct behaviour of copy depends on whether you're writing a GUI app or a commandline tool?)  But both seem to preserve the permissions, something else that std.file.copy doesn't.  (OTOH, DOS and Windows copy operations seem to differ in which attributes they preserve, while both preserve the timestamp.)

Moreover, ITLR we also need something that'll work on arbitrarily large files, and preferably with O(1) rather than O(n) memory requirement.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
March 01, 2005
GNU cp has a '-p' parameter which preserves timestamps.  But, as you say, the default is to no preserve them.

FYI:
One of the things (there are probably many, I'd guess) that makes GNU cp complex is the support for sparse files.  Some filesystems have the ability to save space by not allocating any disk space for blocks that are all zeroes.  GNU cp has the capability to take an existing file, detect the 0 blocks in it, and then in the new file only write the blocks that are nonzero.

Stewart Gordon wrote:
> Nick wrote:
> 
>> In article <d0064p$rgm$2@digitaldaemon.com>, Matthew says...
>>
>>>> I imagine that there's also an OS call on Unix platforms to do it, though I haven't as yet found it.
>>>
>>>
>>> There may be some on individual flavours, but I'm moderately sure it's not a standard UNIX thing.
>>
>>
>> I'm pretty sure too. For fun I downloaded and checked the source for 'cp' from gnu.org.
> 
> 
> Any recollection of the exact URL?  I can't seem to find it with a quick look.
> 
>> It looks mighty long and complicated, not as small and elegant a program as you would think.
> 
> 
> That suggests that a file copy operation on Unix essentially means running this tool.  And it seems that on at least some Unices, copying doesn't preserve timestamps.  When I try from Mac OS X, there seems to be a grey area - copying from Finder preserves the timestamp, but cp from the shell doesn't.  (Does this mean that the correct behaviour of copy depends on whether you're writing a GUI app or a commandline tool?)  But both seem to preserve the permissions, something else that std.file.copy doesn't.  (OTOH, DOS and Windows copy operations seem to differ in which attributes they preserve, while both preserve the timestamp.)
> 
> Moreover, ITLR we also need something that'll work on arbitrarily large files, and preferably with O(1) rather than O(n) memory requirement.
> 
> Stewart.
>