【问题标题】:ZipArchive: `failed to open stream: Is a directory`ZipArchive:`无法打开流:是一个目录`
【发布时间】:2015-08-23 00:56:06
【问题描述】:

我在尝试使用 PHP 解压缩文件时不断收到 failed to open stream: Is a directory 错误。

这通常是目标路径的问题。

但是,就我而言,目的地很好:我可以使用相同的代码解压缩不同的文件,或者不使用 PHP 解压缩相同的文件。

ZipArchive::extractTo 文档没有帮助。此错误消息上的其他 SO 线程也没有。


仅供参考,这是一篇问答帖子。


这是评论中要求的源代码。我公开分享了 Dropbox 链接,因为这取决于 ZIP 输入的格式(ZIP 文件中的/ 路径,请参阅答案。)

/** Config **/
$url = 'https://www.dropbox.com/sh/nx5792q9syppaoo/AAAJZBWlGNAd_EkmQaFvEwe0a?dl=1';

/** Where to save **/
$zipped = ABSPATH . 'tmp/updates/dialogues.zip';    /* Keep in mind this is public-facing. */
$outputdirectory = ABSPATH . 'tmp/updates/testing'; /* The trailing slash is optinal. */

/** Download the dialogues **/
echo 'Fetching the dialogues...<br>';
if ( ( $dropboxfile = fopen( $url, 'r' ) ) === FALSE ) {    /* == has higher precedent over = */
    echo 'FATAL ERROR: could not open Dropbox file.';
    die();
} else if ( file_put_contents( $zipped, $dropboxfile ) === FALSE ) {
    echo 'FATAL ERROR: could not copy Dropbox file.';
    die();
}
echo "Dialogues downloaded as zip OK. (See {$zipped})<br>";


/** Unzip the dialogues **/
print 'Unzipping...<br>';
$zip = new ZipArchive;
$res = $zip->open( $zipped );
if ( $res === TRUE ) {

    // Does not work
    // $zip->extractTo( ABSPATH . 'tmp/updates/testing' );

    // Works
    for( $i = 0 ; $i < $zip->numFiles ; $i++ ) {
        if ( $zip->getNameIndex( $i ) != '/' && $zip->getNameIndex( $i ) != '__MACOSX/_' ) {
            print $zip->getNameIndex( $i ) . '<br>';
            $zip->extractTo( $outputdirectory, array($zip->getNameIndex($i)) );
        }
    }

    $zip->close();
    print 'Done unzipping.<br>';
} else {
    print 'FATAL ERROR: unzipping failed.';
}

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 为什么我想帮忙的时候是-1?
  • 我花了 15 分钟整理这个问答,希望它能在未来节省一些时间,而我已经有了答案。并不完全让我想在未来再次分享问答。
  • 当您尝试解压缩包含名称以点“.”结尾的目录的文件时,也会发生这种情况。见 bugs.php.net/bug.php?id=77214

标签: php zip ziparchive


【解决方案1】:

事实证明,我在 ZIP 存档中有一个 /“文件夹”。

这可以通过命令行浏览 ZIP 存档来确认。例如,在 OS X 上,使用 unzip -vl dialogues.zip 给了我这个:

Archive:  dialogues.zip
 Length   Method    Size  Ratio   Date   Time   CRC-32    Name
--------  ------  ------- -----   ----   ----   ------    ----
       0  Defl:N        2   0%  08-22-15 12:07  00000000  /
    2154  Defl:N     1064  51%  06-08-15 15:18  602c6793  dialogue001-en.txt
    ...
    4379  Defl:N     1793  59%  08-21-15 13:56  75e1ef52  dialogue106-en.txt
      70  Defl:N       39  44%  08-22-15 12:07  985af458  __MACOSX/_
--------          -------  ---                            -------
  775512           343864  56%                            312 files

该文件是从 Dropbox 下载的,我希望能够按原样使用它。

所以在决定解压缩任何给定文件之前,我只是过滤了 ZIP 存档中包含的文件列表:

print 'Unzipping...<br>';
$zip = new ZipArchive;
$res = $zip->open( $zipped );
if ( $res === TRUE ) {
    // 
    for( $i = 0 ; $i < $zip->numFiles ; $i++ ) {
        if ( $zip->getNameIndex( $i ) != '/' && $zip->getNameIndex( $i ) != '__MACOSX/_' ) {
            print $zip->getNameIndex( $i ) . '<br>';
            $zip->extractTo( $tempdirectory, array($zip->getNameIndex($i)) );
        }
    }
    $zip->close();
    print 'Done unzipping.<br>';
} else {
    print 'FATAL ERROR: unzipping failed.';
}

没有在任何地方看到此文档,并在此浪费了近一个小时。我希望这会对某人有所帮助。

我仍然不清楚 ZIP 文件中的 / 引用是否正确。 (欢迎评论。)

【讨论】:

  • 当您尝试解压缩包含名称以点“.”结尾的目录的文件时,也会发生这种情况。见 bugs.php.net/bug.php?id=77214
  • 感谢分享。从 Dropbox 下载的文件也有同样的问题。我不确定为什么 Dropbox 在 zip 中添加 /
猜你喜欢
  • 2013-01-11
  • 2018-02-12
  • 2014-05-21
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
相关资源
最近更新 更多