Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

This is in regards to literally saving a file inside a database

A user there shows you can use a  my $file = <FH> to get the contents of a file to transport into the database.

How would you do this from an upload form without first shoving the file onto your web server, reading the contents, pushing it into the database and finally deleted the uploaded file from the server?

my $uploadfile = param('upload'); open(FILE, "$uploadfile") or die "error: $!"; my $source = <FILE>; close (FILE);
The above fails and I'm not sure why. When you print $uploadfile originally you get the entire C:\\path\to\file\name.file . That goes without saying but when you open it, is it really trying to open from this location? I expected it to be in memory already but something somewhere isn't right.

Is there a way to do this without first saving the file to the disk?

Replies are listed 'Best First'.
Re: File source from memory
by Tanktalus (Canon) on Feb 18, 2005 at 18:03 UTC

    You need to check CGI a bit more carefully in the section entitled "CREATING A FILE UPLOAD FIELD". You don't open the $uploadfile. You can read from it directly as if it were a filehandle. This is, IMO, kinda silly. So, instead, you can get the filehandle directly using my $fh = CGI::upload('upload');. If you don't want to save it at all, check out CGI::upload_hook (which is not exported by default).

      Thanks for your help. After reading what you wrote and what was on CGI again, it's still not running smoothly.
      my $fh = CGI::upload('upload'); print $fh;
      Still returns the C:\\path\name. (as I expected).
      while (<$fh>) { print; }
      Print out the file (from the docs) prints out just fine but it's not saving it.

      So I went back and tried to read in <$fh> and it says it cant be found.

      my $fh = CGI::upload('upload'); open(FILE, "$fh") or die "error: $!"; my $source = <FILE>; close (FILE);
      I can get it to print to the screen but it's saving either just the file name OR nothing at all and errors out.
Re: File source from memory
by maard (Pilgrim) on Feb 18, 2005 at 19:07 UTC

    First, beware that different browsers send file name differently, if you expect to use that file name. IE sends full file path while Opera sends just the basename of file. And if you want your file saved on host use something like

    my $file_name = CGI::param('file_field'); $file_name =~ s:^.*[\\/](.*)$:$1:; # remove path if present my $fh = CGI::upload('file_field'); if ( $fh ) { open(OUT, '>', "/dir/to/save/$file_name"); while (<$fh>) { print OUT $_; } close OUT; } else { # handle the error }

    If you don't need the file name you may don't bother about it's correctness and just read from filehandle (which is $fh - the value that CGI::upload gives you) and send file data to whatever destination you need.

      Thanks for your help, I do know I have to strip the file name but I do NOT want to save the file to my server. I want to read the data from the file directly and write it to the database. How can I do this without first saving the file?

        Notice the scalar reference when using this technique.
        #!/usr/bin/perl #Do you want to use a perl variable as if it were a file? #Previous versions of perl had IO::Stringy and IO::Scalar for that. #Perl 5.8 with PerlIO has it natively. Just use a reference to #the scalar in the filename slot of open. my $foo = ''; open FILEHANDLE, '+>', \$foo or die $!; my $count = 0; for(1..100){ print FILEHANDLE $count; # print "$foo\n"; # select(undef,undef,undef,.1); $count++; } close FILEHANDLE or die $!; print "###########################\n"; print "$foo\n";

        I'm not really a human, but I play one on earth. flash japh