Perlについて。


下記ソースコードを実行すると、以下ような結果になります。

◆結果◆
unix申込書.txt
c:\windows\win申込書.txt
::home:hoge:mac申込書.txt

以下のような結果にならないのはなぜでしょうか?
◆希望(パス名を削除して、ファイル名だけを表示。)◆
unix申込書.txt
win申込書.txt
mac申込書.txt

-----ソースコード ここから--------------------------------------------

use File::Basename;

$file_unix = q|c/windows/unix申込書.txt|;
$file_win = q|c:\windows\win申込書.txt|;
$file_mac = q|::home:hoge:mac申込書.txt|;

print getFileName($file_unix), "<br />";
print getFileName($file_win), "<br />";
print getFileName($file_mac), "<br />";

sub getFileName{
my $path = shift;
my ($name, $path, $suffix) = fileparse($path, ());

return ( $name );
}

-----ソースコード ここまで--------------------------------------------

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2008/02/20 11:04:20
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:tkyk3 No.3

回答回数60ベストアンサー獲得回数7

ポイント60pt

コメント欄には書けないのでこちらに(ポイントはいりません)。

すみません、2の補足です。

「クックブック」ではなく、

CGIプログラミング

CGIプログラミング

  • 作者: スコット グーリッジ ガンザー バージニックス シシャ ガンダヴァラム
  • 出版社/メーカー: オライリー・ジャパン
  • メディア: 単行本

でした。

ここの112ページから、ファイルのアップロードに関する記述があり、結論から言えば、システムで判別するのは難しい(100%ではないという点で)ので、アップロードされるファイル名をテキストフィールドにユーザ側で入力してもらうという至極単純な方法に落ち着くということでした。(ご希望と異なりますが…)

この本によれば、以下のような経緯があります:

一応以下のように書けばWindows,Mac,Unixのシステムに対応できるとあります。

my( $file ) = $q->param( "file" ) =~ m|([^/:\\]+)$|;

ただし、これですと、

ファイル名の一部が取り除かれてしまう場合があります。例えば、Macの場合、"report 11/3/99" は有効なファイル名ですが、上のコマンドだと"99"になってしまいます。

それで、以下のような方法が考えられるということで、

my $file = $q->param( "file" );
$file =~ s/([^\w.-])/_/g;
$file =~ s/^[-.]+//;

と書かれてしますが、これはこれで問題があるようです。

詳細は、p112~118をご覧ください。

本というものは本当に便利です。最初は本なんて…と思いWebだけで勉強していたのですが、やっぱり紙はありがたいです。本の良さを再認識しました。もし読まれていないようでしたら、一度手に取ってみられることをおすすめいたします。(大層なことを言える者ではありませんが…。)

id:tetlis

明確なこたえはなさそうですね。残念です。

たしかに本はありがたいですね。

そして、なんだか説得力があります。書いてあることは正しい、という。

とても丁寧にいろいろ教えていただき、ありがとうございました。

2008/02/20 11:03:50

その他の回答2件)

id:cubick No.1

回答回数129ベストアンサー獲得回数39

ポイント20pt

fileparse_set_fstype($fstype); で明示的にOSを指定してみて下さい。

デフォルトでは実行時のOSに依存するようです。


use File::Basename;

$file_unix = q|c/windows/unix申込書.txt|;
$file_win = q|c:\windows\win申込書.txt|;
$file_mac = q|::home:hoge:mac申込書.txt|;

print getFileName($file_unix), "<br />\n";
fileparse_set_fstype("MSWin32");
print getFileName($file_win), "<br />\n";
fileparse_set_fstype("MacOS");
print getFileName($file_mac), "<br />\n";

sub getFileName{
my $path = shift;
my ($name, $path, $suffix) = fileparse($path, ());

return ( $name );
}
id:tetlis

自動判定はできないということでしょうか?

実際にはHPのフォームに添付されたファイル名からパスを削除したいと思っています。

フォームを利用する人のOSは1つには絞れないので困ってしまいます。

2008/02/14 18:57:30
id:tkyk3 No.2

回答回数60ベストアンサー獲得回数7

前回答えましたが、id:cubickさんの回答を見て、大きな勘違いをしていることに気づきました。

実行プログラムの環境の判別はするかもしれないが、アップロードしてくるクライアントの環境は考慮していないので、意味がないと言うことです。間違った回答になっていたようですみません…

ですから、1番目の回答通り、直に指定する必要があるかもしれません。その際には、クライアントのOS情報もチェックして分岐する、という手法になるかと思います。

あとは、utf8::decodeでUTF8フラグを付けてみる方法は試してみたでしょうか。

 utf8::decode ( $file );
 $file =~ s/.*\\//g;
 utf8::encode ( $file );

これで、バイト単位ではなく文字単位になるかなと思うのですが…これまた間違っていたらすみません。確か、この話に似たものが

Perlクックブック〈VOLUME1〉

Perlクックブック〈VOLUME1〉

  • 作者: トム クリスチャンセン ネイザン トーキントン
  • 出版社/メーカー: オライリージャパン
  • メディア: 単行本

にあった気がします。

id:tkyk3 No.3

回答回数60ベストアンサー獲得回数7ここでベストアンサー

ポイント60pt

コメント欄には書けないのでこちらに(ポイントはいりません)。

すみません、2の補足です。

「クックブック」ではなく、

CGIプログラミング

CGIプログラミング

  • 作者: スコット グーリッジ ガンザー バージニックス シシャ ガンダヴァラム
  • 出版社/メーカー: オライリー・ジャパン
  • メディア: 単行本

でした。

ここの112ページから、ファイルのアップロードに関する記述があり、結論から言えば、システムで判別するのは難しい(100%ではないという点で)ので、アップロードされるファイル名をテキストフィールドにユーザ側で入力してもらうという至極単純な方法に落ち着くということでした。(ご希望と異なりますが…)

この本によれば、以下のような経緯があります:

一応以下のように書けばWindows,Mac,Unixのシステムに対応できるとあります。

my( $file ) = $q->param( "file" ) =~ m|([^/:\\]+)$|;

ただし、これですと、

ファイル名の一部が取り除かれてしまう場合があります。例えば、Macの場合、"report 11/3/99" は有効なファイル名ですが、上のコマンドだと"99"になってしまいます。

それで、以下のような方法が考えられるということで、

my $file = $q->param( "file" );
$file =~ s/([^\w.-])/_/g;
$file =~ s/^[-.]+//;

と書かれてしますが、これはこれで問題があるようです。

詳細は、p112~118をご覧ください。

本というものは本当に便利です。最初は本なんて…と思いWebだけで勉強していたのですが、やっぱり紙はありがたいです。本の良さを再認識しました。もし読まれていないようでしたら、一度手に取ってみられることをおすすめいたします。(大層なことを言える者ではありませんが…。)

id:tetlis

明確なこたえはなさそうですね。残念です。

たしかに本はありがたいですね。

そして、なんだか説得力があります。書いてあることは正しい、という。

とても丁寧にいろいろ教えていただき、ありがとうございました。

2008/02/20 11:03:50
  • id:b-wind
    CGI::Upload というモジュールで似たようなことをやっていますが、
    結局内部でユーザーエージェントによるOS判別をしていますね。
    http://search.cpan.org/dist/CGI-Upload/lib/CGI/Upload.pm
    確実な方法はなさそうです。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません