php遍历一个文件夹并压缩到zip
private function zip($path,$zipFile){
$zip=new ZipArchive();
$zip->open($zipFile,ZipArchive::CREATE);//创建一个空的zip文件
$this->addFileToZip($path,$zip);
}
private function addFileToZip($path,ZipArchive $zip,$root=''){
if(!is_dir($path)){
return false;
}
if(!$root){
$root= $path;
}
if(strpos($path,$root)!==0){
$root= $path;
}
$handler=opendir($path); //打开当前文件夹由$path指定。
while(($filename=readdir($handler))!==false){
if($filename != "." && $filename != ".."){//文件夹文件名字为'.'和‘..’,不要对他们进行操作
if(is_dir($path."/".$filename)){// 如果读取的某个对象是文件夹,则递归
$this->addFileToZip($path."/".$filename, $zip,$root);
}else{ //将文件加入zip对象
$filenameWithPath = $path."/".$filename;
$localFileName = substr($filenameWithPath,strlen($root));
$zip->addFile($filenameWithPath,$localFileName);
}
}
}
@closedir($handler);
}
使用yield重构代码
private function zipFolder($folder,$zipFile){
$zip=new ZipArchive();
$zip->open($zipFile,ZipArchive::CREATE);//创建一个空的zip文件
foreach($this->yieldFile($folder) as $file){
$localFileName = substr($file,strlen($folder));
$zip->addFile($file,$localFileName);
}
}
private function yieldFile($path){
if(is_dir($path)){
$handler = opendir($path);
while(($filename=readdir($handler))!==false){
if($filename != "." && $filename != "..") {//文件夹文件名字为'.'和‘..’,不要对他们进行操作
if(is_dir($path."/".$filename)){// 如果读取的某个对象是文件夹,则递归
foreach($this->yieldFile($path."/".$filename) as $file){
yield $file;
}
}else{ //将文件加入zip对象
$file = $path."/".$filename;
yield $file;
}
}
}
closedir($handler);
}
}
代码执行
public function anyZip(){
for($i=0;$i<6;$i++) {
$start = microtime(true);
$toPath = 'D:/unzip';
$this->zipFolder($toPath, 'd:/zip/123.zip');
$end = microtime(true);
echo '|zipFolder-delay:' . ($end - $start);
$start = microtime(true);
$toPath = 'D:/unzip';
$this->zip($toPath, 'd:/zip/124.zip');
$end = microtime(true);
echo '|zip-delay:' . ($end - $start) . '<br>';
}
}
|zipFolder-delay:1.6427090167999|zip-delay:1.6077039241791
|zipFolder-delay:1.6132049560547|zip-delay:1.6287071704865
|zipFolder-delay:1.6342070102692|zip-delay:1.6152048110962
|zipFolder-delay:1.6917150020599|zip-delay:1.6022040843964
|zipFolder-delay:1.6297070980072|zip-delay:1.7262189388275
|zipFolder-delay:1.5997030735016|zip-delay:1.5892019271851
使用yield递归和正常的递归执行时间差距不大,主要好处是将数据获取和数据处理拆分开,更易理解和复用
分享到:
相关推荐
### Python 递归遍历文件夹并打印满足条件的文件路径实例详解 #### 一、背景与需求 在日常开发工作中,我们经常会遇到需要搜索指定目录及其子目录下的特定文件或处理某些文件的需求。例如,查找包含特定字符串的...
总结起来,遍历文件夹并建立目录树是一个涉及操作系统接口、递归算法和数据结构的问题。通过动态控制深度和优化递归,我们可以有效地遍历任意深度的文件结构,同时利用生成器和目录树数据结构降低资源消耗,实现高效...
这段代码也是使用递归方式遍历指定路径下的所有文件和文件夹,并在控制台上打印出相应的目录结构。 **代码详解:** ```ruby def get_file_list(path) Dir.entries(path).each do |sub| if sub != '.' && sub != ...
### 方法一:递归遍历 第一种方法是通过递归函数实现遍历。在Ruby中,你可以自定义一个递归函数来遍历目录及其子目录中的所有文件。这种方法直观地模拟了树形结构的遍历过程,对于理解和操作文件系统非常有帮助。 ...
foreach遍历是C#常见的功能,而本文通过实例形式展现了C#使用yield关键字让自定义集合实现foreach遍历的方法。具体步骤如下: 一般来说当我们创建自定义集合的时候为了让其能支持foreach遍历,就只能让其实现...
当执行遇到`yield`时,函数暂停并返回一个值,但保持其状态。当下一次调用生成器时,它会从上次离开的地方继续,而不是重新开始。 在递归生成器中,`yield`语句被用来在每次递归调用之间传递控制。递归生成器的一个...
这段代码定义了一个`filter_files`函数,它可以接收目录路径、文件模式、是否只遍历一层以及是否包含文件夹等参数。通过这种方式,我们可以更加灵活地控制遍历过程。 #### 三、总结 通过上述内容,我们了解到了...
`yield`语句是生成器的核心,它暂停函数的执行并将值返回给调用者。当调用者再次请求值时,函数会从上次暂停的地方继续执行。 针对题目中的需求,我们可以创建一个名为`flat`的生成器函数,它接受一个嵌套字典作为...
StreamingAssets文件夹被设计用来存放那些在构建过程中不会被压缩或混淆的静态资源,比如HTML文件、JSON数据、音频文件等。本教程将详细讲解如何在Unity打包后读取该文件夹下的Html文件,并结合手机功能实现邮件发送...
本文将深入探讨如何使用`yield`遍历多个可迭代对象。 首先,让我们了解一下可迭代对象(iterable)。在Python中,可迭代对象是指那些可以被`for`循环遍历的对象,如列表、元组、字符串、字典等。这些对象都实现了`_...
yield关键字的引入,为PHP的文件操作带来了革命性的变化,它使得在内存受限的环境下,遍历和读取大文件成为可能。在实际应用中,yield可以与各种迭代器进行配合使用,通过合理的数据处理策略,可以有效避免程序在...
这是因为 Yield() 函数需要检测消息队列中的消息,并将控制权转移给其他对象,这需要一定的时间开销。因此,在使用 Yield() 函数时需要权衡其优缺点,选择合适的使用场景。 在实践中,Yield() 函数可以与其他技术...
`os.walk()`函数可以帮助我们递归地获取文件夹内的所有文件和子文件夹: ```python import os def get_python_files(directory): for root, dirs, files in os.walk(directory): for file in files: if file....
本文实例讲述了Python 生成器,迭代,yield关键字,send()传参给yield语句操作。分享给大家供大家参考,具体如下: demo.py(生成器,yield关键字): # 生成器是一个特殊的迭代器。可以用for...in遍历。 # 带有...
4. **递归遍历**:从一个起始页面出发,提取出所有符合条件的链接,然后对这些链接进行相同的操作,直到达到预设的深度限制或遍历完所有页面。 以下是一个简单的Python代码片段,展示如何从一个页面提取所有符合...
例如,可以定义一个read_file函数,该函数逐块读取文件内容,并通过yield产生每个块。这种方式对于处理大文件尤其有用。 在使用yield表达式时,有一些特殊的函数,比如next()和send()。next()函数用于获取生成器的...
yield 关键字可以让我们在需要时生成枚举项,而不是将所有枚举项一次性生成并返回。这样可以减少内存的使用和提高性能。 在上面的例子中,我们使用 yield 关键字来生成一个 IEnumerable<string> 对象,而不是生成一...
`flatten`函数就是一个这样的例子,它接收一个可能包含嵌套列表的列表作为参数,并通过递归地处理每个元素来展开它们。如果元素是列表,函数会递归地调用自身;否则,它会将非列表元素作为生成器的输出。以下是`...