2016-10-04 36 views
5

Ben tamsayılaranlamıyla

Array 
(
    [0] => Array 
     (
      [0] => 1531412763 
      [1] => 1439959339 
      [2] => 76 
      [3] => 122 
      [4] => 200 
      [5] => 4550 
      [6] => 444 
     ) 
... 

Ve bu veritabanı sanki ben ona bakarsanız böyle devam herhalde bir dizi var, ikili veri dosyasına yazın - dıştaki dizinin elemanları satırlarıdır ve iç dizilerin elemanları sütunlardır.

Bu bilgiyi bir dosyaya kaydetmek istiyorum, böylece daha sonra alabileceğim, ancak alan kazanmak için ikili veri olarak kaydetmek istiyorum. Temel olarak, 1531412763 örneğinden ilk tamsayı bir dosyaya yazarsam 10 bayt alır, ancak imzalı bir tam sayı olarak kaydedebilseydim 4 bayt alır.

fwrite kullanılmasını önerdiğim diğer yanıtlara baktım, bu şekilde nasıl kullanılacağını anlayamıyorum?

+0

[paketi] (http://php.net/manual/en/function.pack.php)? – Zimmi

+0

Eğer * gerçekten * yerden tasarruf etmeniz gerekiyorsa, verileri neden sıkıştırmıyorsunuz? Bu noktada da olabilir. – Andrew

+0

@Zimmi evet, tam olarak ihtiyacım olan şey buydu, ama her bir değerde 'pack'i çağırmam mı gerek yoksa daha kolay bir yol var mı? –

cevap

3

Bir dosyaya ikili veri yazmak için pack() ve unpack() işlevlerini kullanabilirsiniz. Paket ikili bir dizgi üretecektir. Sonuç bir dizge olduğundan, initleri tek bir dizeyle birleştirebilirsiniz. Ardından bu dizeyi dosyanıza bir satır olarak yazın.

Bu şekilde, dosyayı bir dizi satır içine yerleştirecek olan file() ile kolayca okuyabilirsiniz. Sonra her satır sadece unpack() ve orijinal dizinin geri döndü. Böyle

şey:

$arr = array(
    array (1531412763, 1439959339), 
    array (123, 456, 789), 
); 

$file_w = fopen('binint', 'w+'); 

// Creating file content : concatenation of binary strings 
$bin_str = ''; 
foreach ($arr as $inner_array_of_int) { 
    foreach ($inner_array_of_int as $num) { 
     // Use of i format (integer). If you want to change format 
     // according to the value of $num, you will have to save the 
     // format too. 
     $bin_str .= pack('i', $num); 
    } 

    $bin_str .= "\n"; 
} 

fwrite($file_w, $bin_str); 
fclose($file_w); 


// Now read and test. $lines_read will contain an array like the original. 
$lines_read = []; 
// We use file function to read the file as an array of lines. 
$file_r = file('binint'); 

// Unpack all lines 
foreach ($file_r as $line) { 
    // Format is i* because we may have more than 1 int in the line 
    // If you changed format while packing, you will have to unpack with the 
    // corresponding same format 
    $lines_read[] = unpack('i*', $line); 
} 

var_dump($lines_read); 
+1

Ve her satır aynı sayıda öğeyi içeriyorsa, hatta yeni satırlara bile ihtiyacınız yoktur, sadece ikiliye dönüştürüldüğünde satır uzunluğunu hesaplamanız ve sonra '' fread ($ handle, $ length) '). –

+0

Kesinlikle! Ve söz konusu son yorumunuzda önerdiğiniz gibi formatı optimize edin. – Zimmi

+0

Bu yöntemi kullanarak, düz metinleri depolamak yerine biraz yer tasarrufu sağlamayı başardım. 2,72GB'den 400MB'ye düştüğünde, bu '6.8' kat azalma! –