【PHP入門2021】ファイルから指定バイト数読み込む関数freadの使い方

PHP

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

ファイルシステム関数一覧

fopen

fclose

flock

feof

fgetc

fgets

fread

fwrite/fputs

fgetcsv

fputcsv

file

file_get_contents

file_put_contents

コメント

タイトルとURLをコピーしました