From bbolker at gmail.com  Fri Jan 27 18:03:01 2012
From: bbolker at gmail.com (Ben Bolker)
Date: Fri, 27 Jan 2012 12:03:01 -0500
Subject: [Rd] misfeature: forced file.copy() of a file over itself truncates
 the file ...
Message-ID: <4F22D8C5.5040602@ufl.edu>


  Try this:

  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' ...

  I don't know whether there's any simple way to fix this, or whether
it's just a case of "don't do that".  It might be worth mentioning in
the documentation:

 `file.copy' will normally refuse to copy a file to itself, but in
cases where the same file is referred to by different names (as in
copying "/full/path/to/filename" to "filename" in the current working
directory), it will truncate the file to zero.

  Now that I write that it really seems like a 'mis-feature'.
  On a Unix system I would probably compare inodes, but I don't know if
there's a good system-independent way to test file identity ...

$ ls -i tmp.dat
114080 tmp.dat
$ ls -i /home/bolker/R/pkgs/r2jags/pkg/tests/tmp.dat
114080 /home/bolker/R/pkgs/r2jags/pkg/tests/tmp.dat

  Would normalizePath() work for this ... ?

> normalizePath("tmp.dat")
[1] "/mnt/hgfs/bolker/Documents/R/pkgs/r2jags/pkg/tests/tmp.dat"

   sincerely
    Ben Bolker



[Rd] misfeature: forced file.copy() of a file over itself truncates the file ...
Ben Bolker