スレッド表示 | フラット表示〕 全トピック 920 件中 365 番目 次≫ ≪前

ファイルの上書き

created: 2005-09-27 12:17 | modified: 2005-09-27 17:46 | reply: 2

[2568] ファイルの上書き

user: らいと | created: 2005-09-27 12:17
また質問させていただきます。
宜しくお願いします。

複数行書き込まれているファイルの例えば4行目だけ書き換えたい時はどうしたらいいのでしょうか?

今は一度全部配列に呼び込んで変更したい場所を変更してファイルを空にしてからまた全ての配列を書き込むという方法をとっています。

これだと「ファイルから読み込む」時と「ファイルを空にする」時と「ファイルに再度書きこむ」時に1回に3度ファイルアクセスする事になります。

もっと簡単に出来ると思うのですが何かいい方法あったら教えて下さい。

宜しくお願いします。
reply: 2577 返信 編集 削除

[2577] Re: ファイルの上書き

user: ach | created: 2005-09-27 17:40
“ファイルに再度書きこむ”の時に
$fp = fopen($fileName,"w");
とすれば勝手にファイルが空になりますから2回のアクセスになります。

1回で行うには
$fp = fopen($fileName,"r+");

/* すべて読み込んでから、変更を加えて */

rewind($fp);
fwrite($fp,$data);
ftruncate($fp,strlen($data));
といっても実際には読み書きを2回しているのでfopenのコスト削減程度です。
fseekをうまく使えば、書き換える行から下だけへの書き込みというのもできます。考えてみてください。

本当に4行目だけ書き換えるには、ちょっと今時ではない方法になります。
ファイルに書き込まれる一行の長さを固定長にするという方法です。(実際には改行コードは入りません)
たとえば1行が1024文字で4行目を書き換えたい時は
define("LENGTH",1024);
$fp = fopen($fileName,"r+");

//4行目に移動し、読み込み fseekはEOFより先までポインターが移動できるので注意
fseek($fp,(4-1)*LENGTH);
$data = fread($fp,LENGTH);

/* $dataを変更 */

//$dataのサイズををLENGTHにする
$data = (strlen($data) > LENGTH)? substr($data,0,LENGTH-1) : str_pad($data,LENGTH,chr(0));

//4行目に移動し書き込み
fseek($fp,(4-1)*LENGTH);
fwrite($fp,$data,LENGTH);
fclose($fp);
しかし、リソースを無駄使いしますし、LENGTHの変更も容易ではありません。
それとこの方法を使っても、PHPやOSが間に入っているのでディスクアクセスの削減は保証されていません。
Parent: 2568  reply: 2578 返信 編集 削除

[2578] ありがとうございました。

user: らいと | created: 2005-09-27 17:46
achさん>
とてもスマートなプログラムになりました。

ありがとうございました。
Parent: 2577  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 365 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑