MW211 EXIT

devlog
PHP/fread()とチャンクサイズの関係
2013年09月20日
fread()の読込終了条件の一つとして、以下がある。
「バッファつきで読み込まれた、プレーンなファイルでないストリームの場合に、
  一回の読み込みバイト数がチャンクサイズ(通常は 8192)に達した。
  それまでにバッファされていたデータの内容によって、
  返されるデータのサイズはチャンクサイズより大きくなることがあります。」
読みようによっては「fread($fp, 8192);」までしか
第二引数が指定できないように見える。
だけど、実際は結構無制限(PHPのメモリサイズとの相談となる)。
  ・テキストファイル読込時は無制限でOK
  ・URLを指定してHTML読込時も無制限でOK

つまり「バッファつき…ストリームの場合」ってのは結構イレギュラーなケースっぽい。
で、どんなケースなのかというと、「ユーザ定義のストリーム」ってやつを
読み込む時が対象みたい。

「ストリーム」機能って、シーケンシャルに読み込めるものなら
なんでも対象となる便利なPHPの機能っぽいが、今一よくわからない。

引き続き調査。
分類:PHP、【未解決】
設計/チャンクサイズ
2013年09月19日
「チャンクサイズ(Chunk_Size)」。
「Chunk」は「塊」の意。よって、データを区切る大きさのことを言う。
RAIDアレイ管理の場合は「ストライプサイズ」とも。
これらの総称として「ブロックサイズ」がある。
分類:設計
PHPダウンロード/readfile()の代案のおまけ
2013年09月18日
「readfile()」で大容量ファイルを扱うと以下のエラーがでるといった。
┌──────────────────────────────────────┐
│Fatal error:  Allowed memory size of xxxxxxxxx bytes exhausted              │
│                                   (tried to allocate xxxxxxxxx bytes) in …│
└──────────────────────────────────────┘

これと同じで「fread()」の第二引数で、一回の読み込みサイズを
物凄く大きく指定した場合(ループせずに一回で済まそうとした場合)も、
これと同じエラーとなる。
┌──────────────────────────────────────┐
│@readfile($参照ファイル);                                                   │
├──────────────────────────────────────┤
│$fp = fopen($参照ファイル, 'rb');                                           │
│fread($fp, 大きなサイズ);                                                   │
│fclose($fp);                                                                │
└──────────────────────────────────────┘

つまりまとめて(メモリに)読み込んで一気に提供(標準出力)すると
中間バッファに限界があるが、ループして小出しに提供すれば
中間バッファが小さくても足りるということだ。

【追記】出力バッファリングをオフにすれば「readfile()」が使えると判明
分類:PHP
PHPダウンロード/readfile()の代案
2013年09月17日
「readfile()」は「fread()」(のループ)で代替することができる。

以下のような感じとなる。
┌──────────────────────────────────────┐
│@readfile($参照ファイル);                                                   │
├──────────────────────────────────────┤
│set_time_limit(0);                                                          │
│$fp = fopen($参照ファイル, 'rb');                                           │
│while (!feof($fp)) {                                                        │
│    echo fread($fp, 8192);                                                  │
│}                                                                           │
│fclose($fp);                                                                │
└──────────────────────────────────────┘
「readfile()」はあまり気にすることない、PHP処理時間上限ってのに注意。

つまり、PHP処理時間上限ってのを
「php.ini」の「max_execution_time」(既定値30秒)で定義しているわけだが、
この処理時間がこれを超えると強制的に打ち切られてしまう。

大容量のダウンロードを行った場合、時間がかかると
強制的に打ち切られて、中途半端なダウンロードファイルが提供されてしまうのだ。

ということで、その設定を変えるか、その代案として
先頭で「set_time_limit(0)」実行し、一時的にこれを無制限にするかする必要がある。

ま、そもそもはそんな長時間かけてダウンロードするような設計は避けた方がよい
ということなのだろうけど、必要に直面した場合には
(「fread()」による代案も含め)このような回避方法があるということだ。


【追記】出力バッファリングをオフにすれば「readfile()」が使えると判明
分類:PHP
PHPダウンロード/readfile()は大きなファイルには使えない
2013年09月16日
便利な「readfile()」だが、大容量のファイルをダウンロードする場合に、
使えないという弱点がある。。
もし、これを行った場合、以下のようなエラーがダウンロードされる。
┌──────────────────────────────────────┐
│Fatal error:  Allowed memory size of xxxxxxxxx bytes exhausted              │
│                                   (tried to allocate xxxxxxxxx bytes) in …│
└──────────────────────────────────────┘
但し、一般的には「@readfile()」のように「@」を付けて
エラーメッセージを抑止しているので空のファイルがダウンロードされるだろう。
この場合は「@」を外してもう一度実行してみるとよい。

で、この原因なのだが、「readfile()」はダウンロードファイルを
一旦すべてメモリ上に展開してしまうため、
大容量ファイルだとメモリが足りなくなってしまうのだ。

使えるメモリは「php.ini」の「memory_limit」で定義しているので
この値を大きくすれば対応できる場合もあるが、物理的にメモリが限られているので、
この範囲内でしか調整ができない。
#もちろんPHP内の他でもメモリは消費されるので、ダウンロードファイルの
  サイズぎりぎりってわけにはいかない(大きめにとらなければならない)

ということで、代案が必要だが、次回。

【追記】出力バッファリングをオフにすれば「readfile()」が使えると判明
分類:PHP
PHPダウンロード/readfile()
2013年09月15日
簡単にいえば「readfile()」は、指定された(内部)ファイルを
そのままダウンロードファイルとして提供してくれる便利な関数だ。
┌──────────────────────────────────────┐
│header('Content-Disposition: attachment; filename="ダウンロード先名"');     │
│header('Content-Type: application/octet-stream');                           │
│@readfile($ダウンロード元ファイルパス);                                     │
└──────────────────────────────────────┘
こんな感じで使う。ファイルパス($ダウンロード元ファイルパス)と
公開されるファイル名(ダウンロード先名)を指定するだけで
後は煩雑な処理をまとめてやってくれる。

なお、「readfile()」の前に「@」を付けてエラーメッセージを抑止しているのは
もしエラーが発生した場合、その内容がダウンロードファイルとして
公開されてしまうので、それを防ぐためだ。
分類:PHP
Linux/二重圧縮(zip)
2013年09月14日
「tar」コマンドを二回連続で実行すると上書されたが、「zip」コマンドの場合は?

まず一回目。
┌──────────────────────────────────────┐
│$ zip z.zip a.txt                                                           │
│  adding: a.txt (deflated ??%)                                              │
└──────────────────────────────────────┘
そして二回目。
┌──────────────────────────────────────┐
│$ zip z.zip b.txt                                                           │
│  adding: b.txt (deflated ??%)                                              │
└──────────────────────────────────────┘

さて、結果は?解凍してみよう。
┌──────────────────────────────────────┐
│$ unzip z.zip                                                               │
│Archive:  z.zip                                                             │
│  inflating: a.txt                                                          │
│  inflating: b.txt                                                          │
└──────────────────────────────────────┘
なんとこちらは追加になる。

ちなみに圧縮するファイルの中身(「a.txt」など)が同名の場合には、
上書されるようだ。
分類:Linuxシェル
Linux/二重圧縮(tar)
2013年09月13日
「tar」を二回連続して実行した場合。

まず一回目。
┌──────────────────────────────────────┐
│$ tar -cf z.tar a.txt                                                       │
│$ tar -tf z.tar                                                             │
│a.txt                                                                       │
└──────────────────────────────────────┘

そして二回目。
┌──────────────────────────────────────┐
│$ tar -cf z.tar b.txt                                                       │
│$ tar -tf z.tar                                                             │
│b.txt                                                                       │
└──────────────────────────────────────┘
上書されてしまう。

上書されて困る場合には「--backup=numbered」を付けると、世代管理しつつ
バックアップしてくれる。
┌──────────────────────────────────────┐
│$ tar --backup=numbered -cf z.tar b.txt                                     │
└──────────────────────────────────────┘
この場合だと、「z.tar.~1~」といった退避ファイルができる。
世代管理が不要なら「--backup」だけでもバックアップされる。


上書自体をエラーではじく方法は…?
わからない。事前に「ls」とかで確認して分岐か?
オプションとかあればいいんだが、とにかく既定は強制上書のようだ。
分類:Linuxシェル
C言語/memcpy()の注意点
2013年09月12日
┌──────────────────────────────────────┐
│memcpy(コピー先のアドレス, コピー元のアドレス, サイズ);                     │
└──────────────────────────────────────┘
「memcpy()」は、コピー先をコピー元で潰すイメージがあるので、
コピー先のサイズを超えてコピーしないか常に注意しがちだ。
(もちろん、それをやってしまうと例外が発生する)
ということで、「コピー先のサイズ≧サイズ」は常にチェックするだろう。
しかし、潰されないコピー元も、関係ないところを参照することになると
こちらも例外が発生する。
「コピー元のサイズ≧サイズ」も常に意識しなければならないのだ。
これは結構盲点だ。
分類:C/C++
英訳/非推奨
2013年09月11日
┌──┬───────────────────────────────────┐
│英文│A is deprecated in favor of B.                                      │
├──┼───────────────────────────────────┤
│和訳│AはBが好んで用いられるようになったので使わないほうが良い。          │
│    │つまり、Aは非推奨なので、Bに乗り換えた方がよい。                    │
├──┼───────────────────────────────────┤
│実例│WARNING: "pear/Archive_Zip" is deprecated in favor of "pecl/zip"      │
└──┴───────────────────────────────────┘
分類:英訳
前へ 1 2 3 次へ