misfeature: forced file.copy() of a file over itself truncates the file ...
Ben Bolker <bbolker <at> gmail.com> writes:
Bump. Will I be scolded if I submit this as a bug report/wishlist item? Test case:
fn <- "tmp.dat"
x <- 1:3
dump("x",file=fn)
file.info(fn) ## 9 bytes
file.copy(paste("./",fn,sep=""),fn,overwrite=TRUE)
file.info(fn) ## 0 bytes (!!)
Normally file.copy() checks and disallows overwriting a file with
itself, but it only checks whether character string 'from' is the same
as character string 'to' and not whether the copy refers to the same
file by different names, so it lets this go ahead. It then creates a
new file with the name of 'to' using file.create():
?file.create? creates files with the given names if they do not
already exist and truncates them if they do.
This trashes the existing 'from' file (which was not detected).
file.copy() then happily appends the contents of 'from' (which is now
empty) to 'to' ...
[snip]
My proposed fix (thanks to W. Dunlap) is to use normalizePath();
as he points out, this won't catch situations where the same file
can be referred to via an NFS mount, but it should help at least.
Writing a platform-independent version a la S-PLUS's match.path()
seemed to much work at the moment.
===================================================================
--- files.R (revision 58240)
+++ files.R (working copy)
@@ -116,7 +116,7 @@
if(nt > nf) from <- rep(from, length.out = nt)
okay <- file.exists(from)
if (!overwrite) okay[file.exists(to)] <- FALSE
- if (any(from[okay] %in% to[okay]))
+ if (any(normalizePath(from[okay]) %in% normalizePath(to[okay])))
stop("file can not be copied both 'from' and 'to'")
if (any(okay)) { # care: file.create could fail but file.append work.
okay[okay] <- file.create(to[okay])
thanks
Ben Bolker