php 如何读取 zip 存档中的单个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10420112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 22:06:45  来源:igfitidea点击:

How to read a single file inside a zip archive

phpzipgzipzlib

提问by e-info128

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 as such extracting the whole thing is not a viable solution for me. How can I read a single file?

我需要读取 zip 文件中单个文件“test.txt”的内容。整个 zip 文件是一个非常大的文件 (2gb),包含很多文件 (10,000,000),因此提取整个文件对我来说不是一个可行的解决方案。如何读取单个文件?

回答by Rocket Hazmat

Try using the zip://wrapper:

尝试使用zip://包装器

$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_contentstoo:

您也可以使用file_get_contents

$result = file_get_contents('zip://test.zip#test.txt'); 
echo $result;

回答by Rain

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

请注意,fopen如果 zip 文件受密码保护,@Rocket-Hazmat解决方案可能会导致无限循环,因为如果发生错误,fopen它将失败并且feof始终为真。

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

这解决了无限循环问题,但如果您的 zip 文件受密码保护,那么您可能会看到类似

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

警告:file_get_contents(zip://file.zip#file.txt):无法打开流:操作失败

There's a solution however

不过有解决办法

As of PHP 7.2 support for encrypted archives was added.

从 PHP 7.2 开始,添加了对加密档案的支持。

So you can do it this way for bothfile_get_contentsandfopen

所以,你可以做这样两个file_get_contentsfopen

$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 usingZipArchive

然而,在读取文件之前检查文件是否存在而不用担心加密档案的更好解决方案是使用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 locateNamemethod you need to pass it like folder/with a forward slash at the end.

注意:要使用locateName方法定位文件夹,您需要像folder/在末尾使用正斜杠一样传递它。