ファイル上書き

CGIPHPでのhttpサーバーサイドプログラミングはそこそこ長く続けています。
勉強する時に使ったのは、とほほ(http://www.tohoho-web.com/)さんのところです。
 
今日は、ファイルの上書き手順について、ちょっとした考察を書いてみます。


とほほのWWW入門では、ファイル上書きの仕方について、次の様に書かれています。
(これは現在、ネット上で、最も普及している正しいファイル上書き手順だと思います)

  1. open (ただし、オープン時ファイルの内容はそのまま…つまり"r+"や"a"や"a+")
  2. lock
  3. truncate (サイズを0にする)
  4. seek
  5. write
  6. close

しかし、私は自分でプログラムを組む時は、次の手順を使ってファイル上書きを行っています。

  1. open ("r+"を使う)
  2. lock
  3. write
  4. truncate (書き込んだサイズまでで切る)
  5. close

後者の方法は、前者の方法に比べ、2つのメリットがあります。
 
最初のメリットは……まぁお恥ずかしいことに……私、レンタルサーバーを借りていまして、使用可能なハードディスク容量が決められているのです。
それでですね……前者の方法で上書きを行うと、ハードディスク容量を超えていた場合に、サイズ0のファイルを作ってしまうことになります。
しかし後者の方法だと、書き込み前のファイルサイズと同じところまでは、データが失われずに済みます。(増えた分については、消えてしまう可能性があります)
……まぁ、契約容量いっぱいまで使うなと言われれば、それまでですが。
 
次に、これはサーバー上でちゃんと計測したわけじゃないのですが(Windows上で普通のアプリケーションを書く時は、後者の方が明らかに速い……UNIX上では計測したことないです)、おそらく後者の方法のほうが、ファイル操作コストが少ないと思われることです。
ファイルというのは、ハードディスク上に、malloc・freeのような感じでメモリが割り当てされています。(断片で散らばってはいますが)
それで、書き込み時に足りない場合は、必要な分をそのつど追加で確保しながら書き込みを行うわけです。
つまりですね……前者の方法は一旦全て解放してしまって、そこから更に全て確保するわけです。
後者の方法だと、差分だけを確保or解放することになります。
(まぁ、OSによっては、この辺の最適化がかけられている可能性はありますが、どちらにしても後者の方が確実に高速なんじゃないかと思っています)
 
ただし後者の方法は、書き込み中のサーバーダウン時とかに、途中までが新しくて途中からが古いっていう、変なファイルができてしまう可能性はあります。
でも前者の方法にしても、同じ状況下で、途中から切れてるファイルができてしまう可能性はあるわけです。
これをどう見るべきかとか、難しいところではあるでしょう。
 
……後者の方法、他にどのぐらい使っている人がいるのか……興味あります。