How to read a single file inside a zip archive

后端 未结 2 1533
南旧
南旧 2020-11-28 14:17

I need to read the content of a single file, \"test.txt\", inside of a zip file. The whole zip file is a very large file (2gb) and contains a lot of files (10,000,000), and

相关标签:
2条回答
  • 2020-11-28 14:48

    Please note @Rocket-Hazmat fopen solution may cause an infinite loop if a zip file is protected with a password, since fopen will fail and feof will always be true if an error occurs.

    You may want to change it to

    $handle = fopen('zip://file.zip#file.txt', 'r');
    $result = '';
    if ($handle) {
        while (!feof($handle)) {
            $result .= fread($handle, 8192);
        }
        fclose($handle);
    }
    echo $result;
    

    This solves the infinite loop issue, but if your zip file is protected with a password then you may see something like

    Warning: file_get_contents(zip://file.zip#file.txt): failed to open stream: operation failed

    There's a solution however

    As of PHP 7.2 support for encrypted archives was added.

    So you can do it this way for both file_get_contents and fopen

    $options = [
        'zip' => [
            'password' => '1234'
        ]
    ];
    
    $context = stream_context_create($options);
    echo file_get_contents('zip://file.zip#file.txt', false, $context);
    

    A better solution however to check if a file exists or not before reading it without worrying about encrypted archives is using ZipArchive

    $zip = new ZipArchive;
    if ($zip->open('file.zip') !== TRUE) {
        exit('failed');
    }
    if ($zip->locateName('file.txt') !== false) {
        echo 'File exists';
    } else {
        echo 'File does not exist';
    }
    

    This will work (no need to know the password)

    Note: To locate a folder using locateName method you need to pass it like folder/ with a forward slash at the end.

    0 讨论(0)
  • 2020-11-28 14:55

    Try using the zip:// wrapper:

    $handle = fopen('zip://test.zip#test.txt', 'r'); 
    $result = '';
    while (!feof($handle)) {
      $result .= fread($handle, 8192);
    }
    fclose($handle);
    echo $result;
    

    You can use file_get_contents too:

    $result = file_get_contents('zip://test.zip#test.txt'); 
    echo $result;
    
    0 讨论(0)
提交回复
热议问题