tranthaihoang
tranthaihoang

Reputation: 491

How to upload file in Mojolicious like CGI Perl?

I have a problem when using Mojo::Upload it is not the same as uploading CGI file perl. I need to read the lines in the CSV file uploaded, with the below code of CGI, it can work!

my $upfile = $cgi->param('file');
my $originhead;

while(my $line = <$upfile>){
    $originhead = $line if($first_count == 0);
    $first_count++;
}

$originhead = 'id, abc, cda' it is ok

For Mojo, it doesn't work

use Mojo::Upload;
my $upfile = $self->req->upload('file');

 my $originhead;

    while(my $line = <$upfile>){
        $originhead = $line if($first_count == 0);
        $first_count++;
    }
$originhead = null  fail

Thanks in advance!

Upvotes: 0

Views: 284

Answers (1)

Grinnz
Grinnz

Reputation: 9231

Check out the Mojo::Upload docs. Mojo::Upload is not a filehandle; to read the contents of the uploaded file, the easiest way is to use the slurp method, or if you really want to read it line by line, you can convert it to a File asset and retrieve the handle from that.

use Mojo::Base 'Mojolicious::Controller';

sub action {
  my $self = shift;
  my $upfile = $self->req->upload('file');
  my $contents = $upfile->slurp;
  my $originhead = (split /^/, $contents)[0];

  # or
  my $file = $upfile->asset->to_file;
  my $handle = $file->handle;
  my ($originhead, $first_count);
  while (my $line = <$handle>) {
    $originhead = $line unless $first_count;
    $first_count++;
  }
}

To parse a CSV, Text::CSV is usually much simpler than alternatives.

use Text::CSV 'csv';
my $array_of_hashes = csv(in => \$contents, headers => 'auto', encoding => 'UTF-8') or die Text::CSV->error_diag;

Or for line-by-line processing:

my $csv = Text::CSV->new({binary => 1, auto_diag => 2});
binmode $handle, ':encoding(UTF-8)' or die "binmode failed: $!";
$csv->header($handle);
while (my $row = $csv->getline_hr($handle)) {
  ...
}

Upvotes: 1

Related Questions