Dear Monks,
I'm having a problem with a program that I am writing that is supposed to split a file up into equal pieces. I can read the file size, and I can figure out the size of the pieces I need to write, but when I try to write a file of X bytes in length, that's when the powers of Perl have stupified me.
Here is my code:
#!/path/to/perl -w
use strict;
if($#ARGV!=1){
&usage();
exit(1);
}
my $filename=$ARGV[0];
my $parts=$ARGV[1];
my $totallength = &getsize($filename);
my @part = &calculateparts($totallength, $parts);
&readfile($filename, @part);
exit(0);
sub getsize{
# Read file and get it's TOTAL size
open(FILE, $filename) or die "can't open $filename: $!";
binmode(FILE);
binmode(STDOUT);
my $totallength=0;
while (read(FILE, my $buff, 8 * 2**10)) {
$totallength = $totallength + length $buff;
}
close (FILE) || die "Can't close\n";
return $totallength;
}
sub calculateparts{
# Calculate how many parts are needed
# and how many bytes should be in each part
my ($totallength, $parts) = @_;
my $bytecount = $totallength/$parts;
if ($bytecount == int $bytecount){
for (my $count=1; $count <= $parts; $count++){
# print "Part number $count will be $bytecount bytes long\n
+";
$part[$count] = $bytecount;
}
} else {
my $difference = $totallength - int ($bytecount) * $parts;
my $addition = int ($bytecount) + 1;
for (my $count=1; $count <= $parts; $count++){
if ($difference > 0){
# print "Part number $count will be $addition bytes lon
+g\n";
$part[$count] = $addition;
$difference--;
} else {
# print "Part number $count will be " . int ($bytecount
+) . " bytes long\n";
$part[$count] = $bytecount;
}
}
}
return @part;
}
sub readfile{
my ($filename, @part) = @_;
my $filename2 = $filename;
$filename2 =~(s/(.*)\..*/$1/);
my $count=1;
open (IN,"$filename") || die "can't open $filename for reading
+$!";
while(<IN>) {
my $rv = read(IN, my $buffer, 4096) || die "Couldn't read from
+ $filename $!\n";
# $rv is the number of bytes read,
# $buffer holds the data read
if (!$part[$count]) {last;}
#print "part[count] is $part[$count]\n";
# if ($rv != $part[$count]){print "Number of bytes read: $rv\n
+";}
my $filename3 = "$filename2.$count";
open (OUT, ">$filename3");
print OUT $buffer;
close (OUT);
my $pos = tell(IN);
print "I'm $pos bytes from the start of $filename.\n";
$count++;
}
close(IN) || die "Can't close $filename:$!";
}
sub usage{
$0 =~(s/.*\\(.*)\..*/$1/);
my $Filename = uc($0);
if ($^O =~ /Win/) { system"CLS"; } else { system"CLEAR";}
print "\nUSAGE:\n";
print "\n\t$Filename <filename> <parts>\n";
print "\twhere:\n\n";
print "\t<filename> is the file to be chopped\n";
print "\t<parts> are the number of pieces to chop it into\n";
print "\n";
print "\tERRORLEVEL is set to 0 on Normal Exit\n";
}
I know it's not pretty and I would appreciate information on cleaning it up as well.
Thanks in advance for all your help.