2015-10-20 59 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