За последние 24 часа нас посетили 21897 программистов и 1001 робот. Сейчас ищут 668 программистов ...

Запись бинарных файлов

Тема в разделе "Прочие вопросы по PHP", создана пользователем at0m1x, 3 мар 2014.

  1. at0m1x

    at0m1x Активный пользователь

    С нами с:
    18 дек 2011
    Сообщения:
    31
    Симпатии:
    0
    Как правильно записывать и считывать бинарные файлы на PHP?
    Ниже код, который выдает такую ошибку:

    Код (Text):
    1.  
    2. Warning: unpack(): Type I: not enough input, need 4, have 1
    Т.е. не срабатывает ф-я feof. Хотя достигнув конца файла она должна остановить цикл. Возможно, при записи бинарного файла нужно самому записывать и символ EOF?

    Код (Text):
    1.  
    2. //id,login,email,phone
    3. $users = [
    4.     [1, 'user1', 'user1@mail.com', 786214569851],
    5.     [2, 'user2', 'user2@mail.com', 786214569852],
    6.     [3, 'user3', 'user3@mail.com', 786214569853],
    7. ];
    8.  
    9. $bin = '';
    10. foreach ($users as $values) {
    11.     list($id, $login, $email, $phone) = $values;
    12.     $loginLength = strlen($login);
    13.     $emailLength = strlen($email);
    14.  
    15.     $bin .= pack("I2a{$loginLength}Ia{$emailLength}I", $id, $loginLength, $login, $emailLength, $email, $phone);
    16. }
    17.  
    18. $handle = fopen('users.bin', 'wb');
    19. fwrite($handle, $bin);
    20. fclose($handle);
    21.  
    22. //---------------------
    23.  
    24. $users = [];
    25. $handle = fopen('users.bin', 'rb');
    26. while(!feof($handle)) {
    27.     $data = fread($handle, 4);
    28.     $data = unpack('Iid', $data);
    29.     $result['id'] = $data['id'];
    30.  
    31.     $data = fread($handle, 4);
    32.     $data = unpack('Ilength', $data);
    33.     $loginLength = $data['length'];
    34.  
    35.     $data = fread($handle, $loginLength);
    36.     $data = unpack('a*login', $data);
    37.     $result['login'] = $data['login'];
    38.  
    39.     $data = fread($handle, 4);
    40.     $data = unpack('Ilength', $data);
    41.     $emailLength = $data['length'];
    42.  
    43.     $data = fread($handle, $emailLength);
    44.     $data = unpack('a*email', $data);
    45.     $result['email'] = $data['email'];
    46.  
    47.     $data = fread($handle, 4);
    48.     $data = unpack('Iphone', $data);
    49.     $result['phone'] = $phone;
    50.  
    51.     $users[] = $result;
    52. }
    53. fclose($handle);
    54.  
    55. print_r($users);
    56. die;
     
  2. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Код (PHP):
    1. //id,login,email,phone
    2. $users = [
    3.    [1, 'user1', 'user1@mail.com', 786214569851],
    4.    [2, 'user2', 'user2@mail.com', 786214569852],
    5.    [3, 'user3', 'user3@mail.com', 786214569853],
    6. ];
    7. $countUser=sizeof($users);
    8.  
    9. $bin = '';
    10. foreach ($users as $values) {
    11.    list($id, $login, $email, $phone) = $values;
    12.    $loginLength = strlen($login);
    13.    $emailLength = strlen($email);
    14.  
    15.    $bin .= pack("I2a{$loginLength}Ia{$emailLength}I", $id, $loginLength, $login, $emailLength, $email, $phone);
    16. }
    17.  
    18. $handle = fopen('users.bin', 'wb');
    19. fwrite($handle, $bin);
    20. fclose($handle);
    21.  
    22. //---------------------
    23.  
    24. $users = [];
    25. $handle = fopen('users.bin', 'rb');
    26. while(!feof($handle)) {
    27.     if($countUser === sizeof($users)) {
    28.         break;
    29.     }
    30.    $data = fread($handle, 4);
    31.    $data = unpack('Iid', $data);
    32.    $result['id'] = $data['id'];
    33.  
    34.    $data = fread($handle, 4);
    35.    $data = unpack('Ilength', $data);
    36.    $loginLength = $data['length'];
    37.  
    38.    $data = fread($handle, $loginLength);
    39.    $data = unpack('a*login', $data);
    40.    $result['login'] = $data['login'];
    41.  
    42.    $data = fread($handle, 4);
    43.    $data = unpack('Ilength', $data);
    44.    $emailLength = $data['length'];
    45.  
    46.    $data = fread($handle, $emailLength);
    47.    $data = unpack('a*email', $data);
    48.    $result['email'] = $data['email'];
    49.  
    50.    $data = fread($handle, 4);
    51.    $data = unpack('Iphone', $data);
    52.    $result['phone'] = $phone;
    53.  
    54.    $users[] = $result;
    55. }
    56. fclose($handle);
    57. echo'<pre>';
    58. print_r($users);
    59. die; 
    Надеюсь причину уясните :)
    feof не сможет вызвать true.
     
  3. at0m1x

    at0m1x Активный пользователь

    С нами с:
    18 дек 2011
    Сообщения:
    31
    Симпатии:
    0
    Сделал другим способом, заменил:

    Код (Text):
    1.  
    2. while(!feof($handle)) {
    3. ...
    на

    Код (Text):
    1.  
    2. $size = filesize ('users.bin');
    3. while(ftell($handle) < $size) {
    4. ...
    Работает отлично. Спасибо!
     
  4. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Только будьте внимательны, с большими и весомыми файлами!
    Ибо может возникнуть недоразумение! ;)
    filesize такой ))