fread関数の基本構文
ファイルを指定バイト数読み込みます。
fread ( resource $stream , int $length ) : string|false
パラメータ
型 | 名前 | 初期値 | 説明 |
---|---|---|---|
resource | $handle | fopenで取得したファイルポインタを管理するリソース型のオブジェクト(ファイルハンドラやファイルストリームと同意) | |
int | $length | 読み込むバイト数 |
返り値(戻り値)
型 | 説明 | 例 |
---|---|---|
string|false | 取得したバイト数の文字列。エラーやファイルの終端ならfalseを返す。 |
fread関数の使い方
ファイルから指定バイトずつ読み込み・書き込みする最低限のサンプルソースコード
最低限のファイル入出力処理です。ロック制御やエラー処理は省略しています。
//=======================================================
// ファイルから指定バイト数分読み込んで、別のファイルにコピーしていくサンプル
//=======================================================
$read_file = 'input/line-1.txt'; //読み込みファイル
$write_file = 'output/line-1.txt'; //書き込みファイル
// ファイルのオープン
$fp_r = fopen($read_file, "rb"); //読み込みファイルオープン
$fp_w = fopen($write_file, "wb"); //書き込みファイルオープン
// 読み込みファイルを指定バイトずつ読み込みループする
while (($buffer = fread($fp_r, 4096)) != false) {
// 読み込んだデータを書き込みファイルに書き込み
if(fwrite($fp_w, $buffer) === false){
throw new Exception("書き込みに失敗しました");
}
}
fclose($fp_r); //読み込みファイルクローズ
fclose($fp_w); //読み込みファイルクローズ
exit;
ファイルから指定バイトずつ読み込み・書き込みするサンプルソースコード【ロック&エラー処理あり完全バージョン】
こちらはロック制御やエラー処理を入れたバージョンです。
とっても長いですがWebの本番サービスで同時アクセスの可能性があるファイル処理をやろうとした場合はこれがむしろ最低限のコードになります。
//=======================================================
// ファイルから1行ずつ読み込んで、別のファイルにコピーしていくサンプル
//=======================================================
$start = microtime(true); //開始時間記録
$read_file = 'input/line-1.txt'; //読み込みファイル
$write_file = 'output/line-1.txt'; //書き込みファイル
try{
echo "処理開始 コピー {$read_file} => {$write_file}" . PHP_EOL;
//---------------------------------------
// 読み込みファイルのオープン&ロック処理
//---------------------------------------
$fp_r = fopen($read_file, "rb");
if(is_resource($fp_r) === true){
echo "読み込みファイルオープン成功 {$read_file}" . PHP_EOL;
if (flock($fp_r, LOCK_SH) === true) { // ファイルをロックする(共有ロック)
echo "読み込みファイルのロック成功 {$read_file}" . PHP_EOL;
}else{
throw new Exception("読み込みファイルのロック失敗 {$read_file}");
}
}else{
throw new Exception("読み込みファイルオープン失敗 {$read_file}");
}
//---------------------------------------
// 書き込みファイルのオープン&ロック処理
//---------------------------------------
$fp_w = fopen($write_file, "wb");
if(is_resource($fp_w) === true) {
echo "書き込みファイルオープン成功 {$write_file}" . PHP_EOL;
if (flock($fp_w, LOCK_EX) === true) { // ファイルをロックする(排他ロック)
echo "書き込みファイルのロック成功 {$write_file}" . PHP_EOL;
}else{
throw new Exception("書き込みファイルのロック失敗 {$write_file}");
}
}else{
throw new Exception("書き込みファイルオープン失敗 {$write_file}");
}
//---------------------------------------
// 読み込みファイルを指定バイトずつ読み込みループする
//---------------------------------------
echo "書き込みファイルの行数: " . count(file($write_file)) . PHP_EOL;
$line_num = 0;
while (($buffer = fread($fp_r, 4096)) != false) {
++$line_num;
if($line_num%10000 === 0){ //1000行ごとに進捗出力
$now = microtime(true); //終了時間記録
echo "{$line_num}行目 " . number_format($now - $start, 4) . "秒" . PHP_EOL;
}
//---------------------------------------
// 読み込んだデータを書き込みファイルに書き込み
//---------------------------------------
if(fwrite($fp_w, $buffer) === false){
throw new Exception("書き込みに失敗しました");
}
}
//---------------------------------------
//終了後のチェック
//---------------------------------------
if (feof($fp_r) === false) {
throw new Exception("読み込みファイルが最後まで処理されていません {$read_file}");
}
echo "書き込みファイルの行数: " . count(file($write_file)) . PHP_EOL;
echo "正常終了" . PHP_EOL;
}catch(Exception $ex) {
//---------------------------------------
// エラー処理
//---------------------------------------
echo "エラーメッセージ: " . $ex->getMessage() . PHP_EOL;
} finally { //finallyはPHP5.5より
//---------------------------------------
// 後処理。正常終了・エラー終了のいずれにしても実行
//---------------------------------------
if (is_resource($fp_r) === true) {
echo "読み込みファイルロック解除 {$read_file}" . PHP_EOL;
flock($fp_r, LOCK_UN); //ロック解除
echo "読み込みファイルクローズ {$read_file}" . PHP_EOL;
fclose($fp_r);
}
if (is_resource($fp_w) === true) {
echo "書き込みファイルロック解除 {$write_file}" . PHP_EOL;
flock($fp_w, LOCK_UN); //ロック解除
echo "書き込みファイルクローズ {$write_file}" . PHP_EOL;
fclose($fp_w);
}
}
$end = microtime(true); //終了時間記録
echo "実行にかかった時間: " . number_format($end - $start, 4) . "秒" . PHP_EOL;
exit;
関連するファイルシステム関数
ファイル入出力関数の特徴まとめ
関数 | 利用シーン・特徴 | 機能 | 処理単位 | ハンドル 管理 | ロック (安全性) | 速度 | メモリ節約 | エラー時 |
---|---|---|---|---|---|---|---|---|
fgetc | 1文字ずつ読込 | 読み | 1文字ずつ | 必要 | 別途 自前 | × | ○ | 終端でfalse |
fgets | 1行ずつ読込 | 読み | 1行ずつ | 必要 | 別途 自前 | △ | ○ | 終端かエラー でfalse |
fread | 固定バイトずつ読込 | 読み | 指定バイト | 必要 | 別途 自前 | 指定する バイト次第 ○大量読込 ×分割読込 | 指定する バイト次第 ×大量読込 〇分割読込 | エラーでfalse |
fgetcsv | CSVファイルを 1行ずつ読込 | 読み | 1行ずつ | 必要 | 別途 自前 | × | ○ | エラーで0かnull |
file | 同時書込のないファイルを 行ごとに高速処理する | 読み | データ全部 | 不要 | なし | ○ | × | エラーでfalseや E_WARNING |
file_get_contents | 同時書込のないファイルの 文字列全体を取得 | 読み | データ全部 | 不要 | なし | ○ | × | エラーでfalseや E_WARNING |
fwrite fputs | ハンドル利用時の 書込処理全般 | 書き | 指定バイト | 必要 | 別途 自前 | 指定する バイト次第 ○大量書込 ×分割書込 | 指定する バイト次第 ×大量書込 〇分割書込 | エラーでfalse |
fputcsv | CSVを1行ずつ書込時 | 書き | 1行ずつ | 必要 | 別途 自前 | × | ○ | エラーでfalse |
file_put_contents | 1~数回だけ書込する時。 繰り返しは非常に遅い。 | 書き | データ全部 | 不要 | あり | ○大量書込 ×分割書込 | 指定する バイト次第 ×大量書込 〇分割書込 | エラーでfalse |
コメント