digitalmars.D.bugs - std.file.copy isn't a true copy operation
- Stewart Gordon (41/41) Feb 24 2005 Most of the functions in std.file are written to use OS API functions
- Matthew (5/45) Feb 28 2005 There may be some on individual flavours, but I'm moderately sure it's
- Nick (5/10) Mar 01 2005 I'm pretty sure too. For fun I downloaded and checked the source for 'cp...
- Stewart Gordon (19/31) Mar 01 2005 Any recollection of the exact URL? I can't seem to find it with a quick...
- Russ Lewis (10/49) Mar 01 2005 GNU cp has a '-p' parameter which preserves timestamps. But, as you
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.
Feb 24 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.
Feb 28 2005
In article <d0064p$rgm$2 digitaldaemon.com>, Matthew says...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. NickI 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.
Mar 01 2005
Nick wrote:In article <d0064p$rgm$2 digitaldaemon.com>, Matthew says...Any recollection of the exact URL? I can't seem to find it with a quick look.I'm pretty sure too. For fun I downloaded and checked the source for 'cp' from gnu.org.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.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.
Mar 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...Any recollection of the exact URL? I can't seem to find it with a quick look.I'm pretty sure too. For fun I downloaded and checked the source for 'cp' from gnu.org.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.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.
Mar 01 2005