特に多くのファイルがあり、メモリに直接ロードできないシナリオで大きなファイルを処理する場合、ファイルが変更されたかどうかを判断する必要があることがよくあります。従来のファイル比較方法は、特にファイルサイズが巨大な場合、より多くのメモリを消費する場合があります。したがって、これは、ハッシュ値に基づいてファイルが変更されているかどうかを検出するための効率的で一般的に使用される方法です。
PHPでは、 hash_update_streamを使用してファイルのハッシュ値を徐々に計算し、大規模なファイルの変更の検出を実現できます。この記事では、この関数を使用してファイルコンテンツの変更を確認する方法を詳細に紹介します。
hash_update_streamは、データストリーム(ファイルなど)のハッシュ値を計算するPHPの関数です。ファイルコンテンツを段階的に処理し、ファイルのハッシュ値を計算できます。ファイル全体のハッシュを直接計算するのとは異なり、 hash_update_streamは、ファイル全体を一度にメモリにロードすることを避けるため、大きなファイルに適しています。
ファイルが変更されたかどうかを検出するために、通常、次の手順を通じて実装します。
ファイルのハッシュ値を生成します。まず、ファイルの初期ハッシュ値を生成する必要があります。このハッシュ値は、 hash_update_streamによって計算され、ファイルの元の状態の「指紋」として保存できます。
ファイルのハッシュ値を定期的に確認します。ファイルが変更されたかどうかを確認する必要がある場合は、ファイルのハッシュ値をもう一度計算し、以前に保存したハッシュ値と比較します。
ファイルが変更されているかどうかを判断します。新しいハッシュ値が古いハッシュ値と異なる場合、ファイルが変更されたことを意味します。それ以外の場合、ファイルは変更されていません。
上記のチェック関数を実装するには、最初にHASH_UPDATE_STREAMを使用してファイルのハッシュ値を計算する方法を理解する必要があります。これがサンプルコードです:
<?php
// ファイルパスを設定します
$file = 'path/to/your/largefile.txt';
// ファイルを開きます
$stream = fopen($file, 'rb');
if (!$stream) {
die('无法ファイルを開きます');
}
// 使用 hash_update_stream ファイルハッシュ値を徐々に計算します
$context = hash_init('sha256'); // 異なるハッシュアルゴリズムを選択できます,例えば sha256
while (!feof($stream)) {
$data = fread($stream, 8192); // ブロックごとにファイルブロックを読み取ります
hash_update_stream($context, $data); // ハッシュ値を更新します
}
// 最終的なハッシュ値を計算します
$hash = hash_final($context);
fclose($stream);
// 出力ファイルのハッシュ値
echo "ファイルのハッシュ値はです: $hash\n";
?>
上記のコードでは、 hash_initを使用してハッシュコンテキストを作成し、 hash_update_streamを介してハッシュ値を徐々に更新します。毎回ファイルストリームからデータのご塊を読み、ファイルが読み取られるまでhash_update_streamに渡します。最後に、 hash_finalを介してファイルの最終的なハッシュ値を取得します。
次に、必要に応じて比較できるように、ファイルのハッシュ値を保存する必要があります。ファイルが変更されたかどうかを確認するためのサンプルコードは次のとおりです。
<?php
// 元のハッシュ値を保存するファイルパス
$hashFile = 'path/to/your/previous_hash.txt';
// 元のハッシュ値を取得します(ある場合)
$previousHash = file_exists($hashFile) ? file_get_contents($hashFile) : null;
// 現在のファイルのハッシュ値を取得します
$file = 'path/to/your/largefile.txt';
$stream = fopen($file, 'rb');
if (!$stream) {
die('无法ファイルを開きます');
}
$context = hash_init('sha256');
while (!feof($stream)) {
$data = fread($stream, 8192);
hash_update_stream($context, $data);
}
$currentHash = hash_final($context);
fclose($stream);
// ある場合之前的哈希值,比較します
if ($previousHash !== null) {
if ($previousHash === $currentHash) {
echo "ファイルは変更されていません。\n";
} else {
echo "ファイルが変更されました。\n";
}
} else {
echo "以前のハッシュ値は見つかりませんでした,无法比較します。\n";
}
// 現在のハッシュ値を保存します,次の比較のために
file_put_contents($hashFile, $currentHash);
?>
このコードでは、最初にファイルから以前に保存したハッシュ値を読み取ろうとします。次に、現在のファイルのハッシュ値を再計算して比較します。ハッシュ値が一貫している場合、ファイルが変更されていないことを意味します。異なる場合、ファイルは変更されています。最後に、次の比較のために現在のハッシュ値をファイルに保存します。
上記の手順を通じて、 hash_update_streamを使用して、大きなファイルが変更されたかどうかを検出できます。ファイル全体をメモリに直接読み込むことと比較して、この方法はメモリの使用とパフォーマンスに明らかな利点があり、非常に大きなファイルの処理に特に適しています。
ハッシュ値の比較により、ファイルコンテンツの整合性チェックを実装して、ファイルが改ざんまたは紛失されていないことを確認できます。
この記事が、PHPでhash_update_stream関数を使用して、大きなファイルの変更を検出し、実際の開発におけるファイル管理効率を改善する方法を理解するのに役立つことを願っています。