On 6/7/07, Tom Phoenix <[EMAIL PROTECTED]> wrote:
On 6/7/07, Perl WANNABE <[EMAIL PROTECTED]> wrote:

> I'm trying to copy a couple of DBM files from a disk to a RAM disk,
> one of the files is 500M the other quite small.

Some DBM implementations, if the filesystem supports doing so, will
create files with "holes" in them; that is, the file may have
arbitrarily long gaps in which there's no data. You can even have a
file that seems larger than the disk it's stored upon.

> Whether I use File::Copy or I roll my own copy by reading and writing the
> file the filesystem fills up... If I use system (cp from to) I don't have a
> problem.

It sounds as if your cp knows how to handle the holes, but File::Copy
isn't so smart. It may be worth filing a bug report over this; even if
File::Copy isn't fixed, its documentation should mention this.

Cheers!

--Tom Phoenix
Stonehenge Perl Training

#create a sparse file
perl -e '
   open my $f, ">", "sparse.txt";
   seek $f, 1024*1024 - 3, 0;
   print $f "foo";
   close $f
'

#copy it with File::Copy
perl -MFile::Copy -e 'copy("sparse.txt", "sparse.fc")'

#copy it with cp
cp sparse.txt sparse.cp

#copy it with SparseCopy*
sparsecopy.pl sparse.txt sparse.scp

#look at the sizes
du -sh sparse.*
8.0K    sparse.cp
1.1M    sparse.fc
8.0K    sparse.scp
8.0K    sparse.txt

#make sure they are all have the same contents
md5sum sparse.*
8d7e9e80e3724b84decdfc7f9b772b41  sparse.cp
8d7e9e80e3724b84decdfc7f9b772b41  sparse.fc
8d7e9e80e3724b84decdfc7f9b772b41  sparse.scp
8d7e9e80e3724b84decdfc7f9b772b41  sparse.txt

#rejoice

* Here is the program**
#!/usr/bin/perl

use strict;
use warnings;

sparsecopy(@ARGV);

sub sparsecopy {
       my ($orig, $new) = @_;

       open my $o, '<', $orig
               or die "could not open $orig: $!";

       open my $n, '>', $new
               or die "could not open $new: $!";

       select $o;

       local $/ = \4096;

       while (defined (my $block = <$o>)) {
               for my $chunk (split /(\0+)/, $block) {
                       if ($chunk =~ /\0/) {
                               seek $n, length($chunk), 1;
                               next;
                       }
                       print $n $chunk;
               }
       }
}

** patents and trademark pending***
*** yeah, right

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to