2017-12-25 9 views
10

मैं मूवी फ़ाइलों के लिए opensubtitles.org हैश की गणना करने के लिए नीचे दिए गए फ़ंक्शन का उपयोग कर रहा हूं। यह ज्यादातर काम करता है लेकिन बड़ी फ़ाइलों के साथ मुझे निम्न त्रुटि मिलती है।ओपनसबिटल्स हैश फ़ंक्शन बड़ी फ़ाइलों के लिए विफल रहता है

मैं वास्तव में इसे समझ नहीं पा रहा हूं क्योंकि हमेशा डेटा उपलब्ध होना चाहिए।

क्या कोई मुझे सही दिशा में इंगित कर सकता है?

पीएचपी चेतावनी: खोल(): प्रकार वी: नहीं पर्याप्त इनपुट, जरूरत 2, लाइन 169

function OpenSubtitlesHash($file) 
{ 
    $handle = fopen($file, "rb"); 
    $fsize = filesize($file); 

    $hash = array(3 => 0, 
        2 => 0, 
        1 => ($fsize >> 16) & 0xFFFF, 
        0 => $fsize & 0xFFFF); 

    for ($i = 0; $i < 8192; $i++) 
    { 
     $tmp = ReadUINT64($handle); 
     $hash = AddUINT64($hash, $tmp); 
    } 

    $offset = $fsize - 65536; 
    fseek($handle, $offset > 0 ? $offset : 0, SEEK_SET); 

    for ($i = 0; $i < 8192; $i++) 
    { 
     $tmp = ReadUINT64($handle); 
     $hash = AddUINT64($hash, $tmp);   
    } 

    fclose($handle); 
     return UINT64FormatHex($hash); 
} 

function ReadUINT64($handle) 
{ 
    $u = unpack("va/vb/vc/vd", fread($handle, 8)); 
    return array(0 => $u["a"], 1 => $u["b"], 2 => $u["c"], 3 => $u["d"]); 
} 

function AddUINT64($a, $b) 
{ 
    $o = array(0 => 0, 1 => 0, 2 => 0, 3 => 0); 

    $carry = 0; 
    for ($i = 0; $i < 4; $i++) 
    { 
     if (($a[$i] + $b[$i] + $carry) > 0xffff) 
     { 
      $o[$i] += ($a[$i] + $b[$i] + $carry) & 0xffff; 
      $carry = 1; 
     } 
     else 
     { 
      $o[$i] += ($a[$i] + $b[$i] + $carry); 
      $carry = 0; 
     } 
    } 

    return $o; 
} 

function UINT64FormatHex($n) 
{ 
    return sprintf("%04x%04x%04x%04x", $n[3], $n[2], $n[1], $n[0]); 
} 
+0

, कृपया हमें बताएं में [email protected] – Justinas

+0

लाइन आपका '$ u = अनपैक (" va/vb/vc/vd ", फ़्रेड ($ हैंडल, 8)); 'यदि आप' var var = fread ($ हैंडल, 8) करते हैं; var_dump ($ var);' क्या आउटपुट है? क्या यह वास्तव में डेटा पढ़ता है? – Tschallacka

उत्तर

1

पर file.php में 0 है, तो आपके $ हैन्डल होता है आप जांच कभी नहीं किसी भी Resoure, जब आपके $ संभाल अशक्त या गलत है तो आप एक ही त्रुटि

PHP Warning: unpack(): Type v: not enough input, need 2, have 0 in file.php on line 169 

मिलता तो एक जांच जोड़ना होगा इससे पहले कि आप $ के साथ कुछ करना संभाल

if(!is_null($handle)){ 
    // Do something.. 
} 
5

यदि आपने कुछ अतिरिक्त जानकारी प्रदान की है: सिस्टम का संस्करण, PHP का संस्करण, बड़ी फ़ाइलों का आकार, फाइलों का प्रकार (सरल फ़ाइलें, यूआरएल, आदि) - यह एक सटीक उत्तर के लिए अधिक जानकारी देगा।

मुख्य धारणा है कि आप 32-बिट सिस्टम पर हैं और 2 जीबी से अधिक फ़ाइलों के साथ filsize के साथ समस्याएं हैं। दस्तावेज़ों से:

नोट: क्योंकि PHP के पूर्णांक प्रकार पर हस्ताक्षर किए गए हैं और कई प्लेटफ़ॉर्म 32 बिट पूर्णांक का उपयोग करते हैं, कुछ फाइल सिस्टम फ़ंक्शन 2 जीबी से बड़ी फ़ाइलों के लिए अप्रत्याशित परिणाम लौटा सकते हैं।

आप शायद गलत filesize मूल्य प्राप्त है और इसलिए नहीं सही ढंग से पीछे चल बाइट्स पढ़ सकते हैं। This comment बताता है कि बड़ी फ़ाइलों का आकार कैसे प्राप्त करें और यह भी नोट करें कि fseek आंतरिक रूप से int का उपयोग करता है ताकि आप 2 जीबी थ्रेसहोल्ड के बाद पॉइंटर नहीं डाल सकें। आपको इस स्थिति में fread की आवश्यकता होगी।

रहे हैं अन्य परिकल्पना की जाँच की जा सकती है:

  • fread कुछ circustances के तहत अनुरोध किया की तुलना में अधिक डेटा पढ़ सकता है:

    यदि धारा बफ़र पढ़ा जाता है और यह एक सादे फ़ाइल का प्रतिनिधित्व नहीं करता, पर सबसे अधिक एक खंड के बराबर बाइट्स (आमतौर पर 8192) के बराबर पढ़ा जाता है; पहले buffered डेटा के आधार पर, लौटा हुआ डेटा का आकार खंड आकार से बड़ा हो सकता है।

  • stat कैश आपको सटीक फ़ाइल आकार मान प्राप्त करने से रोकता है;
0

आप की जरूरत नहीं है और कुल फ़ाइल आकार की गणना नहीं करना चाहिए।फ़ाइल आकार PHP_INT_MAX से अधिक है तो परिणाम सही नहीं होगा,

एक दूर बेहतर समाधान फ़ाइल के अंत से fseek() उपयोग करने के लिए है:

fseek($handle, -65536, SEEK_END); 
संबंधित मुद्दे