Perlで一括アップロードできない理由は何ですか?

このQ&Aのポイント
  • Perlでの一括アップロードがうまくいかない場合、ファイルを書き込むWhileループ内のprint部分が原因と考えられます。
  • アップロードしたファイルの一部は正しいファイル名で生成されますが、サイズが0バイトになってしまいます。
  • バイナリデータも取得できていることから、CGI.pmモジュールの呼び出し部分やエラーチェック部分に問題はなさそうです。
回答を見る
  • ベストアンサー

Perlでの一括アップロード

同じファイルを違うファイル名で一括でアップロードしたいのですが。 最初の一つしか正常にアップされません。 残りのファイルは正しいファイル名で作成はされるのですが、0バイトの状態です。 原因としてはファイルを書き込む Whileの中のprintしている部分かと思われます。 ちなみにバイナリデータも取得できています。 *このソースはファイルのアップ部分だけで、 実際にはforeachの中で関数として呼ばれています。 エラー関数や、モジュールの呼び出し部分は省略しています。 仕様モジュールCGI.pm ソースは以下のとおりです。 ご教授の方よろしくお願いいたします。 # 最大許容サイズ(KByte) my $maxsize = 300; # 保存先ディレクトリ my $logfiles = "./file"; # アップロードを許可するファイルの種類 my %hash_mime = ( 'text/html' => 'html', 'image/jpeg' => 'jpg', 'image/pjpeg' => 'jpg' ); # ファイル取得 my $fH = $query->upload('filename'); # エラーチェック if ($query->cgi_error) { my $err = $query->cgi_error; &error("$err") if ($err); } &error("File transfer error.") unless (defined($fH)); # MIMEタイプ取得 my $mimetype = $query->uploadInfo($fH)->{'Content-Type'}; # 保存するファイル名を取得 my $set = &set_name($mimetype); # ファイル保存 my ($buffer); open (OUT, ">$logfiles/$set") || &error("Can't open $set"); binmode (OUT); while(read($fH, $buffer, 1024)){ print OUT $buffer; } close (OUT); close ($fH) if ($CGI::OS ne 'UNIX'); chmod (0666, "$logfiles/$set");

  • Perl
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

> 同じファイルを違うファイル名で一括でアップロードしたいのですが。 中身一緒なんだから、ファイルを一つだけアップロードして、あとは複数のファイル名(パス)をPOSTして、サーバ側でコピーした方が効率的では。 1回は正しく処理されているようですので、予期した通りにデータが流れてきているかtcpdumpとかのネットワークパケットキャプチャとかで追跡してみては。 プログラムの誤りがあるのだとしたら、今回示されてないコードの部分にありそうな気がします。

hrimfaxi
質問者

お礼

返事が遅くなって申し訳ありませんでした。 ファイルをコピーする方法で解決いたしました。 モジュールを使うバージョンと 読み込み書き込みでコピーするバージョン 2タイプで作成し分岐で汎用性をもたしてみました。 なぜ2番目以降のファイルの書き込みができなかったのかの原因は不明ですが。結果オーライということにしときます。 本当にありがとうございました。

関連するQ&A

  • 画像アップロード機能を追加しようとしましたが、できません

    画像アップロード機能を追加しようとしたのですが、できません。 こちらのhttp://www.new-f.com/に置かれているRPGキャラクターシート管理CGIver2.00に ローカルから画像をアップできるようにしたいと思っております。 こちらhttp://www.ss.iij4u.or.jp/~somali/web/_perl_upload.htmlにcgi.pmを使う方法がありましたので、 ソースをそのまま流用して、ファイルアップができるかどうかを確認し、問題なくファイルアップができましたので、そのソースをを追記してみました。 文法チェッカーなどでは、特に問題ないと出たのですが、入力ををする時点まではできるのですが、 送信すると、500エラーとなってしまいます。 どのようにしたら、画像アップが可能になるでしょうか? それとも、この方法では不可能なのでしょうか? 追記した部分(エディタTeraPad使用/102桁で折り返し) 40行目~ # POSTサイズの上限 $CGI::POST_MAX = 1024 * 1024; # 1MB $query = new CGI; # キャラクタ更新フォーム # 最大許容サイズ(KByte) my $maxsize = 300; # 保存先ディレクトリ my $logfiles = "./imgs"; # アップロードを許可するファイルの種類(MIMEと拡張子) my %hash_mime = ( 'image/gif' => 'gif', # GIFファイル 'image/jpeg' => 'jpg', # JPEGファイル 'image/pjpeg' => 'jpg' # プログレッシブJPEGファイル ); 77、78行目 # 画像アップ upfile(param('upfile')) if ( param('upfile') ); 207行目 <INPUT size="40" type="file" name="upfile"  value="$logfiles/$set"> 686、687行目 if ( $logfiles/$set eq "" || $logfiles/$set eq " "){print OUT "No Photo Data.";} else{print OUT "<img src=\"$logfiles/$set\" width=\"250\" alt=\"キャラクタ画像\">";} 976行目~ sub upfile{ #送られてきたデータを処理する ----------------- # ファイル取得 my $fH = $query->upload('filename'); # エラーチェック if ($query->cgi_error) { my $err = $query->cgi_error; &error("$err") if ($err); } &error("File transfer error.") unless (defined($fH)); # MIMEタイプ取得 my $mimetype = $query->uploadInfo($fH)->{'Content-Type'}; # 保存するファイル名を取得 my $set = &set_name($mimetype); # ファイルサイズ取得 my $size = (stat($fH))[7]; # サイズ制限 &error("The filesize is too large. Max $maxsize KB") if ($size > $maxsize * 1024); # ファイル保存 --------------------------------- my ($buffer); open (OUT, ">$logfiles/$set") || &error("Can't open $set"); binmode (OUT); while(read($fH, $buffer, 1024)){ print OUT $buffer; } close (OUT); close ($fH) if ($CGI::OS ne 'UNIX'); # Windowsプラットフォーム用 chmod (0666, "$logfiles/$set"); } # ファイル名を設定 ----------------------------- sub set_name { my ($mime) = @_; # 拡張子をセット my $ext = $hash_mime{$mime} ? $hash_mime{$mime} : &error("Can't permit this file."); # ファイル名のフォーマット my $set = time . "_" . $$ . "." . $ext; return $set; }

    • ベストアンサー
    • CGI
  • バイナリファイルのアップロードに関して

    今回質問させて頂くことに関連した問題を、現在MySQLのカテゴリで質問させていただいているのですが、 バイナリファイルをアップロードし、そのファイルのバイナリデータを変数($img)に格納し、それをDBに格納するという形を目指しています。しかし、DBにどうしても格納できません。もしやバイナリデータを変数に格納する時点で、既におかしいのかと思いまして、その部分についてこちらでご教授頂きたく書き込ませていただきました。 #!C:\Perl use CGI; use DBI; $PCMOJPATH='C:\パス名'; #ディレクトリ指定 my ($buffer); my $query = new CGI; $uniqid = time . "_" . $$; $newfile = "upload_$uniqid"; #ファイル名 print "Content-type: text/html\n\n"; print "<html><body>\n"; my $fH = $query->upload('filename'); my $mimetype = $query->uploadInfo($fH)->{'Content-Type'}; open (OUT, ">$PCMOJPATH/$newfile"); binmode (OUT); while(read($fH, $buffer, 1024)){ print OUT $buffer; $img .= $buffer;   #バイナリデータを$imgに格納 } close (OUT); close ($fH) if ($CGI::OS ne 'UNIX'); chmod (0666, "$PCMOJPATH/$newfile"); ------------------------- と書いているのですが、$imgにはバイナリデータがちゃんと入っていないのでしょうか?間違っているところがあれば、どのように直したらいいか教えてください。どうぞよろしくお願いします。

  • perlでCSV形式ファイルのアップロード

    本日、同じ質問をしたものです。 前回の問題は解決したのですが、ファイルがアップロードできないで悩んでします。 CGIのプログラムは以下のソースです。 #! c:/perl/bin/perl use CGI; # CGIヘッダーの出力 print "Content-type: text/html\n\n"; my ($query,$fileName); $query = new CGI; $fileName = $query->param('fileName'); open(OUT, ">./a.csv"); binmode(OUT); while(read($fileName,$buffer,1024)) { print OUT $buffer; } close(OUT); close($fileName); #ファイルハンドルをcloseしています。 exit ; ファイルは、作られるのですが、中身が書き込まれません。 どなたか教えてください。 お願いします。

    • ベストアンサー
    • Perl
  • ファイルのアップローダーを動作させたい。

    ファイルをサーバーへ格納するプログラムを検索して作成しました。 見よう見まねなのでおかしい部分があるかもしれません。 entry.cgi #!/perl/bin/perl my $buffer; my $query = CGI->new; my $fh = $query->upload('file') or die(qq(Invalid file handle returned.)); # Get $fh my $file = $query->param('file'); my $file_name = ($file =~ /([^\\\/:]+)$/) ? $1 : 'uploaded.bin'; open(OUT, ">$file_name") or die(qq(Can't open "$file_name".)); binmode OUT; while (read($fh, $buffer, 1024)) { # Read from $fh insted of $file print OUT $buffer; } close OUT; sample.html <HTM><BODY> <FORM METHOD="POST" ENCTYPE="multipart/form-data" ACTION="./entry.cgi"> <TABLE BORDER="1"> <TR><TD ><B>CSVファイル</B></TD> <TD ><INPUT TYPE="FILE" NAME="filename"></TD></TR> <TR></TR> </TABLE> <BR> <BR> <INPUT TYPE="SUBMIT" NAME="GO" VALUE=" 登録の実行 "> </FORM> </BODY></HTML> 上記のプログラムを実行すると 「CGIWrap Error: Script Execution Failed」と表示されてしまいます。 500のサーバーエラーと同じと調べてわかったのですが、どこがどうおかしいのか?わかりません。 perlの記述が今まで自分が使用していたものと勝手が違うので分からない状態です。 アドバイスもらえると幸いです。

  • ファイルのアップロードについて

    PERLでファイルのアップロード機能を作成しています。 アップロードと言っても、サーバへのコピーではなく、 データベースへバイナリで格納しなければならないのです。 とりあえず2パターン作成してみたのですが、 OPEN関数を使ってやるとうまくいきません。 -----パターン1(OPEN関数使用)------------- $query = new CGI; $filename = $query->param('msds'); # ファイル名(フルパス)取得 if($filename ne "") { open(ATT, $filename);# or die "Could not open atachment file:"; binmode(ATT); while($bytesread = read(ATT, $buffer, $BUFSZ)){ $file .= $buffer; # ファイルサイズ制限 $file_size ++; if($file_size > 300){ exitError("ファイルサイズが大きすぎます。600KB 以下にして下さい。"); } } close(ATT); } -----パターン2(OPEN関数未使用)------------- $query = new CGI; $filename = $query->param('temp1'); # ファイル名(フルパス)取得 if($filename ne "") { while($bytesread = read($filename, $buffer, $BUFSZ)){ $file .= $buffer; # ファイルサイズ制限 $file_size ++; if($file_size > 300){ exitError("ファイルサイズが大きすぎます。600KB 以下にして下さい。"); } } print "FILE DATA:" . $file . "<BR>"; } パターン2でprint $fileをすると、ファイルの内容が 画面表示されるのですが、パターン1だと、While文に 入ってくれませんでした。 原因がさっぱりわかりません。。。 お分かりになる方が見えましたらご教授願います。

    • ベストアンサー
    • CGI
  • perl Image::Magick

    恐れ入ります。perlでImage::Magickで画像の処理をしているのですが、画像によって途中までしか変換されていなかったりする画像(下部分が灰色)のものが出ます。この原因と対策をご存じの方はいらっしゃいますか? $filename = "./folder/image.jpg"; $filename 2= "./folder2/image.jpg"; $image = Image::Magick->new; $image->Read("$filename"); $width = $image->Get('width'); $height = $image->Get('height'); $image -> Set( quality => 60 ); $image->Write("$filename2"); 以上のようにしています。HTMLからファイルを受け取る部分は、 my ($query,$fileName); $query = new CGI; $fileName = $query->param('fileName'); open(OUT, ">./folder/image.jpg"); binmode(OUT); while(read($fileName, $buffer, 2048)) { print OUT $buffer; } としています。HTMLからのアップロードは、対象フォルダの画像を確認した場合問題無くアップされています。以上よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlのtruncateについて

    + test.txt 0 1 2 3 + main.cgi open(FH, "+<test.txt"); my @Log = <FH>; truncate(FH, 0); seek($FileHandle, 0, 0); print(FH "4"); close(FH); これで、main.cgiを実行すると、test.txtの中身は 4 1 2 3 となってしまいます。truncateがきいてないようなのですが、なぜでしょうか。 truncate(FH, 0) or die "error"; とすると、errorと表示されてしまいます。 なぜこうなるのでしょうか。 致命的エラーがでるわけでもないので、環境が悪いわけではないような気がするのですが。 flockをしたいのですが、他にファイルの中身を空にする方法とかありませんか。

    • ベストアンサー
    • Perl
  • perlでCSV形式ファイルのアップロード方法

    perlでCSV形式ファイルのアップロード方法を教えてさい。 htmlで <HTML> <BODY> <FORM action="excel読み込み.cgi" enctype="multipart/form-data" method="post"> フレアシステムのファイル: <INPUT type="file" name="upload_file" size="60"><BR> <INPUT type="submit" value="読み込み"> </FORM> </BODY> </HTML> として、ファイル名の指定をして、読み込みボタンを押すと、excel読み込み.cgiを呼び出すのですが、プログラムの内容が表示されるだけで終わってしまいます。 excel読み込み.cgiのプログラムは以下の内容です。 #! c:/perl/bin/perl use CGI; $query = new CGI; $filename = $query->param('upload_file'); while(read($filename, $buffer, 2048)) { $file .= $buffer; } @files = split(/\\/, $filename); ($basename, $exp) = split(/\./, $files[-1]); $new_file = $basename . "." . $exp; # ファイルを指定ディレクトリにコピー #open(OUT, "> c:\\foo\\$new_file"); open(OUT, "> c:\\$new_file"); binmode(OUT); print(OUT $file); close(OUT); print "Content-type: text/html\n\n"; print "[$basename] [$exp]\n"; print "正常終了\n"; exit; CGIのプログラムを色々と調べて、別のないようにしても同じようにプログラムがそのまま表示されてしまいます。 どなたか教えてください。 宜しくお願いします。

  • cgi(perl)でアップロードされたファイルを保存する方法について

    ファイルをアップロードするフォーム"form.html"(method="POST" action="/cgi-bin/form.cgi")を書きました。 ファイルを保存する方法について疑問があるので教えて下さい。 http://www.ss.iij4u.or.jp/~somali/web/_perl_upload.html 上記URLを参考にしました。 下記の変数"$filename"には、アップロードしたファイル名(image.jpgなど)が入っています。 (アップロードされたファイル名と保存するファイル名を同じにしました。) #------------------------------------------------------------ open (OUT, ">$filename") || die "cannot open"; binmode (OUT); $i=1;#ループ回数とアップロードされたファイルのサイズの比較の為。 while(read($filename, $buffer, 1024)){ print OUT $buffer; $i++; } close (OUT); close ($filename) if ($CGI::OS ne 'UNIX'); # Windowsプラットフォーム用 print "whileループの数: $i<BR>"; #------------------------------------------------------------ while文について。 while(read($filename, $buffer, 1024)){ print OUT $buffer; 上記の2行は、1024バイトづつ$filename(アップロードしたファイル名)から読み込み、$bufferに格納。 $bufferに格納されたデータをOUTで指定した部分に書き込む、そしてそれを繰り返す。 こう理解していますが間違いないでしょうか? ファイルサイズが予想できれば、whlie文を使わずに read($filename,$temp,10000); print OUT $temp; このようにしても問題ありませんか? read関数について教えて下さい。 書籍などには、 read(FILEHANDLE,$data,1024); こう書いてありますが、上記例でFILEHANDLEを変数名$filenameにしても問題なく動作しました。 FILEHANDLEでなく、変数$filenameでも問題無いのでしょうか? FILEHANDLEと$filenameは何を示しているんですか? ファイルの先頭アドレスでしょうか? $filenameにはアップロードしたファイル名が入っているのにどうして動くのだろうと疑問に思っています。 乱文で申し訳ありませんがご教授下さい。 宜しくお願い致します。

    • ベストアンサー
    • Perl
  • 固定パスでアップロードする場合

    通常ファイルをアップロードする場合、 test.html ---------------------------------------- <form action="upload_test.cgi" method="post" enctype="multipart/form-data"> <input type="file" name="filename" > <input type="submit" value="送信" > </form> ---------------------------------------- upload_test.cgi ---------------------------------------- my ($query,$filename,$mimetype); $filename = $query->param('filename'); $mimetype = $query->uploadInfo($filename)->{'Content-Type'}; ---------------------------------------- ・・・こんな感じに cgi 側でアップしたいファイルの フルパスを受け取ると思いますが、 test.html で、ファイル名をその際選択せずに、 固定の( できれば hidden で ) textタイプ <input type="text" name="filename" value="C:\Documents and Settings\xxxx\デスクトップ\UP.htm" > という具合で upload_test.cgi にうまくファイルのフルパスを渡すにはどうしたらいいのでしょうか。

    • ベストアンサー
    • Perl

専門家に質問してみよう