Aykhan Amiraslanli
Aykhan Amiraslanli

Reputation: 643

perl web development get local file size

My hosting is not allowed to upload big files to server with PHP. So I need to upload with Perl.

I need to display uploaded file size. And here is my part of code:

open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
binmode UPLOADFILE;

while ( <$upload_filehandle> )
{
print UPLOADFILE;
}

close UPLOADFILE;

$filename = ">$upload_dir/$filename";

use File::stat;
my $stat = stat($filename);
say $stat->size;
 
say stat($filename)->size;

But I got an error:

Can't call method "size" on an undefined value at upload.cgi line 56.

Update

After Borodin's answer I updated to this new code, which is now giving an Internal server error

#!/usr/bin/perl -wT
use strict;
use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;
use diagnostics;
use File::stat;
use warnings;
use 5.010;
... #SOME CODES ##
my $upload_filehandle = $query->upload("photo");

open ( UPLOADFILE, ">$upload_dir/$filename" ) or die "$!";
binmode UPLOADFILE;

while ( <$upload_filehandle> )
{
print UPLOADFILE;
}

close UPLOADFILE;

my $full_name = "$upload_dir/$filename";

{
    open my $up_fh, '>:raw', $full_name or die qq{Unable to open "$full_name" for output: $!};

    print $up_fh, $_ while <$upload_filehandle>;
}

printf "%.2fMB uploaded\n", (-s $full_name) / (1024 * 1024);



print $query->header ( );

Upvotes: 0

Views: 75

Answers (1)

Borodin
Borodin

Reputation: 126722

Your variable $filename is set to >$upload_dir/$filename which is wrong. The > is the mode for the open call and isn't part of the file name

You want

my $filename = "$upload_dir/$filename";

Also, rather than using File::stat etc. you can just use the -s file test operator

say -s $filename;

which is much more concise

I would code the whole thing like this

my $full_name = "$upload_dir/$filename";

{
    open my $up_fh, '>:raw', $full_name or die qq{Unable to open "$full_name" for output: $!};

    print $up_fh, $_ while <$upload_filehandle>;
}

printf "%.2fMB uploaded\n", (-s $full_name) / (1024 * 1024);

Update

You're misunderstanding what my code does. You're opening the upload file twice now -- mine replaces all of that. It should look like this below

The reason you're getting the error is that you're printing the file size before the HTTP header. I don't know what you want your response to look like, but you probably want to wrap it in HTML and print it after $query->header()

#!/usr/bin/perl -T

use strict;
use warnings;
use 5.010;

use CGI;
use CGI::Carp qw ( fatalsToBrowser );
use File::Basename;

#... SOME CODE

my $upload_filehandle = $query->upload('photo');

my $full_name = "$upload_dir/$filename";

{
    open my $uploaded_fh, '>:raw', $full_name or die qq{Unable to open "$full_name" for output: $!};

    print $uploaded_fh $_ while <$upload_filehandle>;
}

my $size = -s $full_name;

print $query->header('text/plain');

printf "\n%dB file uploaded\n", $size;

Upvotes: 2

Related Questions