2015-10-20 20 views
0

如果我有三個GET參數:閱讀散列/校驗文件的大部分

$filename = $_GET['filename']; 
$start = $_GET['start']; 
$size  = $_GET['size']; 

我正在讀的文件的塊,像這樣:

$handle = fopen($basepath . $filename, "rb"); 
fseek($handle, $start); 
$contents = fread($handle, $size); 
echo md5($contents); 

我如何可以讀取大一個文件的部分(從1MB到1GB的任何地方),並創建一個哈希或校驗和的內容,而無需爲整個讀取分配足夠的內存?

目前,如果我嘗試散列太大的文件的一部分,我得到一個內存錯誤,因爲PHP不能分配足夠的內存(大約400mb)。

是否有我可以一次同時消化文件的部分,而不是全部內容的散列函數(例如開始$start讀取100KB塊和飼料它的功能,直到$size滿足)?我該如何讀取文件塊,以便我從$start開始讀$size字節?

如果沒有這樣同時支持數據塊的塊料散列或校驗功能,file_get_contents()修爲大讀分配內存的問題?我不完全確定該功能是如何工作的。

謝謝。

+0

什麼讓一個散列只是一個文件的一部分,目的是什麼? – 2015-10-20 23:52:52

+0

它是下載程序腳本的一部分,客戶端可以下載部分http文件,並要求從服務器端進行比較,以獲取該文件部分的散列/校驗和。 –

+0

爲什麼不使用zip或tar拆分服務器端 – 2015-10-20 23:55:17

回答

0

http://php.net/manual/en/function.hash-update.php

<?php 
define('CHUNK', 65536); 

//$file = 'alargefile.img'; 
//$start = 256 * 1024 * 1024; 
//$size = 512 * 1024 * 1024; 

$fp = fopen($file, "r"); 
fseek($fp, $start); 
$ctx = hash_init('md5'); 
while ($size > 0) { 
    $buffer = fread($fp, min($size, CHUNK)); 
    hash_update($ctx, $buffer); 
    $size -= CHUNK; 
} 
$hash = hash_final($ctx); 
fclose($fp); 
print $hash; 
?> 
+0

這正是我一直在尋找的東西,儘管我相信在閱讀文件時存在一個錯誤。逐個減少'$ size'變量會連續多次產生相同的散列。與'md5​​sum'相比,將'$ start'設置爲0並且'$ size'設置爲文件大小會產生錯誤的md5散列。有任何想法嗎? –

+0

修正了它。問題在於'fgets',據推測它停在換行符上。將其更改爲fread可以解決問題,並且按照它的功能運行。謝謝〜 –

+0

是啊,現在是4點在這裏:(對不起,這將修復 – Sorin