Search A.I.
Menu
ホーム

メールマガジン ホームページプログラミングテク

Windowsテク
Javaアプレット サンプル
Java Q & A
JavaScript Q & A
Perl Q & A
Perl レッスン
PHP レッスン
PHPテク
MS-DOS コマンド集
UNIX コマンド集
SQL コマンド集
SEの基礎講座
WEBシステム開発受注します
]無料フォームメール送信サービス
リンク集
Perl レッスン

1. Perl の基礎
2. Perlの文法、条件式
3. Perlの文法、条件式 - 続き
4. 配列について
5. ハッシュ配列について
6. Perlの基礎 - 続き
7. 関数について
8. 関数について - 続き
9. 文字列操作関数
10. 配列操作関数
11. ファイル操作
12. ファイル操作 - 続き
13. パラメータの受け渡し
14. クッキーについて
15. 総合練習
16. メール送信
17. ファイルアップロード
18. パッケージの使用方法
19. MySQL
20. MySQL - 続き(1)
21. MySQL - 続き(2)
22. PostgreSQL
23. 総合練習
24. 総合練習解答



11. ファイル操作

今日は、ファイル操作について、ご説明いたします。

■ファイル操作の基本
ファイルの読み書きを行うためには、ファイルのオープンとクローズの処理が
基本になります。

open(ファイルハンドル, "ファイル名");

ファイルハンドルというのは、一言で言うと、ファイルを操作するための変数です。
オープン時にファイルハンドルを取得し、読み込みや書き込みも、このファイル
ハンドルに対して行います。

ファイルオープン時には、ファイルを読み込みで開くか、書き込みで開くかを
指定します。ファイル名の部分に、以下の記号で指定します。

open ( FH , " < filename " ); 読込み用
open ( FH , " > filename " ); 書込み用 (上書き)
open ( FH , " >> filename " ); 書込み用 (追加)
open ( FH , " +> filename " ); 読み書き用
open ( FH , " +< filename " ); 読み書き用

ファイルオープン後、ファイル操作が終了したら、必ずファイルをクローズします。

close(ファイルハンドル);

使用例を以下に記述します。

-----------------------------------------------------------------
$filename = "./test.txt";

if (!open(FH, "< $filename")) {
print "ファイルオープンに失敗しました。($filename)";
exit;
}

close(FH);
-----------------------------------------------------------------

open()関数は、ファイルオープンに失敗すると、偽が返ってきますので、
エラー時の処理を書くことができます。

ファイルが存在しない場合や、権限がない場合もエラーとなります。

-----------------------------------------------------------------
※権限について
よくファイル書き込み時につまづくのですが、読み込みや書き込みを行う
ファイルに対して、それぞれ読み込み権限、書き込み権限が必要になります。
WEBサーバがUNIXの場合、ツールやコマンドを使用して権限を変更します。
ファイルが置いてあるディレクトリにも権限がないと、エラーになってしまい
ますので、注意しましょう。Windowsの場合は、読み取り専用になっていると
書き込みができません。
-----------------------------------------------------------------

また、Perlでよく使用されている別の記述方法があります。

-----------------------------------------------------------------
open ( FH , "< $filename ") || die "ファイルを開けません :\n";
-----------------------------------------------------------------

こう記述した場合、open()の結果が偽の場合のみ、die()が実行されます。

if文でもそうですが、"||"を使用した場合、左側の式が真だと、その時点で
全体が真になりますので、右側の式は実行されません。

if (1 || $a = "0") { # 右側の式は実行されない

die()関数は、エラー発生時に、標準出力に第1引数を出力して処理を終了
します。

■ファイルの読み込み
ファイルをオープンした後に、文字列として中身を取り出す方法をご説明します。

$line = <ファイルハンドル>;

ファイルハンドルに対応づけられたファイルの先頭から、1行ずつデータを
読み込みます。1行の区切りとして改行文字が用いられます。通常は、while文で
ループさせます。

-----------------------------------------------------------------
while ($line = <FH>) {
print $line;
}
-----------------------------------------------------------------

上のように記述すると、1回のループで1行取得し、ファイルの最後まで取得
したら、ループを抜けます。

また、

-----------------------------------------------------------------
while (<FH>) {
print $_ . "<br>";
}
-----------------------------------------------------------------

これだけでも、ループで1行ずつファイルの中身を取り出すことができます。
$_で1行ずつデータを取り出します。

@array = <ファイルハンドル>;

ファイルハンドルに対応づけられたファイルの内容を、一括して配列へ代入する
事が出来ます。1行目が $array[0]に、2行目は $array[1]、・・・と格納されて
いきます。

-----------------------------------------------------------------
@array = <FH>;
foreach $tmp (@array) {
print $tmp;
}
-----------------------------------------------------------------

上のように記述するだけで、ファイルの中身を一括で配列に取得します。

read ( ファイルハンドル , 格納変数 , 読み出すバイト長 );

read関数を使用することで、指定したバイト数でファイルデータを取得できます。

-----------------------------------------------------------------
while (<FH>) {
read(FH, $data, 64);
print $data;
}
-----------------------------------------------------------------

上記の場合、ファイルから64バイトずつ、$dataにデータを格納します。

■ファイルの書き込み
ファイルをオープンした後に、ファイルの中身に文字列を書き込む方法をご説明
します。

print ファイルハンドル 出力データ;

ファイルへの出力は通常の print , printf の引数に open で取得したファイル
ハンドルを指定します。それ以外は通常の print文と同じです。

-----------------------------------------------------------------
print FH "File write test.\n";
print FH "This is a file write sample.\n";
-----------------------------------------------------------------

上記のように、ファイルハンドルを第1引数に記述することで、ファイルに
書き込みを行うことができます。

syswrite [ファイルハンドル] , [出力データ] , [出力バイト長];

バイト数を指定して書き込みたい場合は、syswrite関数を使用します。

-----------------------------------------------------------------
syswrite(FH, "File write test.\n", 64);
-----------------------------------------------------------------

指定したバイト数より書き込みデータが多い場合は、データが切り捨てられます。

 

★今日のまとめサンプルプログラム
-----------------------------------------------------------------
#! /usr/local/bin/perl

print "Content-type:text/html\n\n";

print << "END_OF_HTML";
<HTML>
<BODY>
END_OF_HTML

$filename = "./test.txt";
if (!open(FH, "< $filename")) {
print "ファイルオープンに失敗しました。($filename)";
exit;
}

@array = <FH>;
foreach (@array) {
print $_ . "<br>";
}

close(FH);

if (!open(FH, "> ./test2.txt")) {
print "ファイルオープンに失敗しました。(./test2.txt)";
exit;
}

print FH "This is a test sample.\n";

close(FH);

print << "END_OF_HTML";
</BODY>
</HTML>

END_OF_HTML

exit;
-----------------------------------------------------------------

■解説
CGIを置いているディレクトリに、適当に中身を書いた"test.txt"を置いて実行して
みてください。

書き込みの方は、ファイルがない場合は、新しく作成しますので、手動で作成する
必要はありません。

CGIを動かして、同じディレクトリに新しく"test2.txt"が作成されていたら、中身も
確認してみてください。

 

★課題
1. 簡易的なアクセスカウンタを作成してください。
(ヒント)最初は 0 とだけ書いた"count.txt"を作成し、ファイル読み込みを行い、
数字に 1 プラスしたら、それをファイルに上書きし、HTMLにも表示します。

 

★前回の課題の解答
(1) 'sun;mon;tue;wed;thu;fri;sat'という文字列の";"を除いて配列に格納し、
さらに" : "で区切った文字列に連結し、出力する
(2) 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'という文字列の','を
除いて配列に格納し、アルファベットの逆順にソートする
(3) ('sun','mon','tue','wed','thu','fri','sat')という配列で、最初の'sun'を
一番最後に移動する処理
(4) ('name'=>'Ichiro Suzuki','mail'=>'mail@email.co.jp')というハッシュ配列の
ハッシュ値のみを取り出して出力する

→下のサンプルを参照してください。

-----------------------------------------------------------------
#! /usr/local/bin/perl

print "Content-type:text/html\n\n";

print << "END_OF_HTML";
<HTML>
<BODY>
END_OF_HTML

# (1) 'sun;mon;tue;wed;thu;fri;sat'という文字列の";"を除いて配列に格納し、
# さらに" : "で区切った文字列に連結し、出力する
$week = 'sun;mon;tue;wed;thu;fri;sat';
@week = split(/;/, $week);
$week = join(" : ", @week);
print $week . "<br>";

# (2) 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec'という文字列の','を
# 除いて配列に格納し、アルファベットの逆順にソートする
$mon = 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec';
@mon = split(/\,/, $mon);
@mon = reverse(sort(@mon));
print @mon;
print "<br>";

# (3) ('sun','mon','tue','wed','thu','fri','sat')という配列で、最初の'sun'を
# 一番最後に移動する処理
@week = ('sun','mon','tue','wed','thu','fri','sat');
push(@week, shift(@week));
print @week;
print "<br>";

# (4) ('name'=>'Ichiro Suzuki','mail'=>'mail@email.co.jp')というハッシュ配列の
# ハッシュ値のみを取り出して出力する
%hash = ('name'=>'Ichiro Suzuki','mail'=>'mail@email.co.jp');
foreach $value (values(%hash)) {
print $value . "<br>";
}

print << "END_OF_HTML";
</BODY>
</HTML>

END_OF_HTML

exit;
-----------------------------------------------------------------

■解説
だんだんと難しくなってきましたが、レッスンの内容をちゃんと読んでいれば
できるかと思います。

(1)は、split()とjoin()を使います。

(2)は、split()で配列に格納した後、reverse()とsort()を使用して、逆順にソート
します。

(3)は、shift()、push()の順に使用します。1 行で書いていますが、分けても
結構です。

(4)は、ハッシュ値のみを取り出すので、values()を使用します。




前の章へ 次の章へ


このエントリーをはてなブックマークに追加


OfficeLance

お問い合わせはこちらから