[Rd] misfeature: forced file.copy() of a file over itself truncates the file ...
Ben Bolker
bbolker at gmail.com
Tue Jan 31 20:16:09 CET 2012
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
More information about the R-devel
mailing list