原创:IO 类 (主要为常用文件系统操作)

snakevil 2004-03-28 04:08:12
闲暇时信手写的一个类,后来感觉有用就整理了一下,发上来给大家 pp
功能谈不上强大,就把自己想得到的功能实现了
欢迎大家提意见~

1----------------------------------------

/*
*
* ===========Z=================
* QQ:118824
* MSN:snakevil_@hotmail.com
* HP:http://www.snakevil.com/
* ===========Z=================
*
*/

/**
* @]Class Name[= IO
* @]Class URI[= System.IO
* @]Purpose[=
* 本类用于对文件系统的处理
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]Version[= 1.0.1
* @]Create[= 17:13 2004-3-25
* @]Modifications[=
* 7:31 2004-3-27
* + 将错误处理抽象为基类
* + 增加方法 comment_away()
* @]See[=
*/
class IO extends SnkClass {
var $result;
var $last_exist_dir;

function IO() {
parent::SnkClass();
$this->result = array();
$this->error_id = 0x0000;
$this->error_related = "";
$this->last_exist_dir = "";
return $this;
}

/**
* @]Method Name[= list_dir()
* @]Purpose[=
* 读取指定目录内容,返回内容数组
* @]Parameter[=
* string $dir_path 指定目录路径
* @]Return[= mixed 错误返回 FALSE,否则
* array(
* "count"=>array("files","dirs","size"),
* "list"=>array(
* array("name","locate","type","size","last_access","last_change","last_modify"),
* ......
* )
* )
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function list_dir($dir_path=".") {
if (!is_dir($dir_path)) return $this->error_occur(0x0001, $dir_path);
if (!$dir_handle=@opendir($dir_path)) return $this->error_occur(0x0002, $dir_path);
$result = array(
"count" => array("files" => 0, "dirs" => 0, "size" => 0),
"list" => array()
);
while (false!==($file_handle=readdir($dir_handle))) { // 使用 !== 防止处理名称为 0 或 FALSE 的文件、目录
if ($file_handle=="."||$file_handle=="..") continue; // 忽略系统特定的两个文件夹
$temp = str_replace("\\", "/", realpath($dir_path));
$temp = substr($temp, -1)=="/" ? $temp : $temp."/";
$temp = array($temp, $file_handle);
$file_handle = $temp[0].$temp[1]; // 获取绝对地址
$temp = array(
"name" => $temp[1],
"locate" => $temp[0],
"type" => @filetype($file_handle),
"size" => filesize($file_handle),
"last_access" => fileatime($file_handle),
"last_modify" => filemtime($file_handle),
"last_change" => filectime($file_handle)
);
switch ($temp["type"]) {
case "file":
$temp["type"] = 1;
$result["count"]["files"]++;
$result["count"]["size"] += $temp["size"];
break;
case "dir":
$temp["type"] = 0;
$result["count"]["dirs"]++;
break;
default: // !!!! 鉴于 Win32 平台,对既非文件也非目录的内容忽略
$temp["type"] = -1;
}
$result["list"][] = $temp;
}
closedir($dir_handle);
unset($dir_handle, $file_handle, $temp);
clearstatcache(); // 清除文件系统缓存
return $this->result = $result;
}

/**
* @]Method Name[= seek_file()
* @]Purpose[=
* 根据正则表达式条件,在相应目录及给定层次的子目录中搜索匹配的文件、目录
* @]Parameter[=
* regular $pattern 兼容 PERL 标准,无 //,指明搜索匹配要求
* enum $seesk_type 有 -1 0 1 三种可能值,0 仅文件夹,1 仅文件,-1 两者都包括
* int $sub_dir 搜索的子目录深度,指定目录不算,建议不要超过 5
* boolean $interal 为真则返回搜索结果的详细信息,否则只返回文件名、类型及所在目录
* limit $limit 搜索结果限制,避免过度浪费系统资源
* @]Return[= mixed 错误返回 FALSE,否则
* array(
* array(
* "name","locate","type"
* [,"size","last_access","last_change","last_modify"]
* ),
* ......
* )
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function seek_file($pattern=".*",$dir_path=".",$seek_type=1,$sub_dir=0,$interal=false,$limit=100) {
/* 规范一切可能的参数值 */
$pattern = "/".$pattern."/";
$seek_type = intval($seek_type);
$seek_type = $seek_type>0 ? 1 : ($seek_type<0 ? -1 : 0);
$sub_dir = abs(intval($sub_dir));
$interal = (bool)$interal;
$limit = abs(intval($limit));
if ($limit==0) $limit = 100;
$sub_dir_list = array(array($dir_path)); // 将查询目录作为子目录层次的第一层来对待
$result = array();
/* i 当前处理的子目录层次,0 为指定目录层,即仅处理一个目录 */
for ($i=0;$i<=$sub_dir;$i++) {
if (!isset($sub_dir_list[$i])) return $this->result = $result; // 如果某一层子目录没有设置,说明实际目录系统中再无目录,返回
/* k 每一子目录层次中子目录统计,j 当前处理序号 */
for ($j=0,$k=count($sub_dir_list[$i]);$j<$k;$j++) { // 根据每一层子目录数量处理
$l = $this->list_dir($sub_dir_list[$i][$j]);
if (!$l) return $this->result = $result; // 出现错误,则立即停止返回现有结果
$l = $l["list"];
/* n 每一子目录中文件、目录、其他项目统计,m 为当前处理序号 */
for ($m=0,$n=count($l);$m<$n;$m++) {
if (count($result)>=$limit) return $this->result = $result; // 如果要求数目已达到,返回
if ($l[$m]["type"]==0) $sub_dir_list[$i+1][] = $l[$m]["locate"].$l[$m]["name"]; // 搜集下一层子目录信息
$o = $l[$m]["type"];
if ($o!=$seek_type&&($seek_type==1||$seek_type==0)) continue; // 忽略不符合要求的项目
elseif ($o==-1&&$seek_type==-1) continue;
if (!preg_match($pattern, $l[$m]["name"])) continue; // 忽略不符合正则表达式的项目
$result[] = $interal ? $l[$m] : array("name" => $l[$m]["name"], "locate" => $l[$m]["locate"], "type" => $l[$m]["type"]);
}
}
}
unset($i, $j, $k, $l, $m, $n, $o, $sub_dir_list);
return $this->result = $result;
}
...全文
41 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
snakevil 2004-03-28
  • 打赏
  • 举报
回复
3----------------------------------------

/**
* @]Method Name[= copy()
* @]Purpose[=
* 对任意文件夹、文件进行复制,相对或绝对路径皆可,文件复制完成后会进行效验,检查是否出错数据错误
* @]Parameter[=
* string $src_path 指定要复制的源内容路径,文件或目录均可
* string $dst_path 指定要复制的目标内容路径,文件或目录均可,性质由 $src_path 决定,可为 $src_path 下层目录
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function copy($src_path="",$dst_path="") {
if (!file_exists($src_path)) return $this->error_occur(0x0003, $src_path);
if (!$dst_path=$this->realpath($dst_path)) return false;
if (is_dir($src_path)) {
$this->last_exist_dir = ""; // 记录现行实际存在的目录
if (!$this->make_dir($dst_path)) return false; // 建立目录失败
$src_path = str_replace("\\", "/", realpath($src_path));
$src_path = substr($src_path, -1)=="/" ? $src_path : $src_path."/";
$sub_list = array(array($src_path));
for ($i=0;$i<count($sub_list);$i++) {
if (!isset($sub_list[$i])) break;
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
$l = $this->list_dir($sub_list[$i][$j]);
if (!$l) return $this->error_occur(0x0003, $sub_list[$i][$j]);
$l = $l["list"];
for ($m=0,$n=count($l);$m<$n;$m++) {
$o = $l[$m]["locate"].$l[$m]["name"];
if ($o==$this->last_exist_dir) continue; // 如果为上级目录向下级目录复制,防止死循环
$p = str_replace(substr($src_path, 0, -1), $dst_path, $o);
if ($l[$m]["type"]==0) {
$sub_list[$i+1][] = $o;
if (!$this->make_dir($p)) return false; // 对每一个子目录都予以建立
} else { // 对每一个文件进行复制
if ($this->verify_file($o, $p)) continue; // 如果目标与源完全相同,不再复制
if (!copy($o,$p)||!$this->verify_file($o,$p)) return $this->error_occur(0x0009, $o);
}
}
}
}
unset($i, $j, $k, $l, $m, $n, $o, $p, $sub_list);
return true;
} else {
if (!is_readable($src_path)) return $this->error_occur(0x0006, $src_path);
if ($this->verify_file($src_path,$dst_path)) return true;
$i = strrpos($dst_path, "/");
$dst_path = array(substr($dst_path, 0, $i), substr($dst_path, $i+1));
unset($i);
if (!$this->make_dir($dst_path[0])) return false;
$dst_path = implode("/", $dst_path);
if (!copy($src_path,$dst_path)||!$this->verify_file($src_path,$dst_path)) return $this->error_occur(0x0009, $src_path);
return true;
}
}

/**
* @]Method Name[= move()
* @]Purpose[=
* 对任意文件夹、文件进行移动,相对或绝对路径皆可,文件移动完成后会进行效验,检查是否出错数据错误
* @]Parameter[=
* string $src_path 指定要移动的源内容路径,文件或目录均可
* string $dst_path 指定要移动的目标内容路径,文件或目录均可,性质由 $src_path 决定,可为 $src_path 下层目录
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function move($src_path="",$dst_path="") {
if (!file_exists($src_path)) return $this->error_occur(0x0003, $src_path);
if (!$dst_path=$this->realpath($dst_path)) return false;
if (is_dir($src_path)) {
$this->last_exist_dir = "";
if (!$this->make_dir($dst_path)) return false;
$src_path = str_replace("\\", "/", realpath($src_path));
$src_path = substr($src_path, -1)=="/" ? $src_path : $src_path."/";
$sub_list = array(array($src_path));
for ($i=0;$i<count($sub_list);$i++) {
if (!isset($sub_list[$i])) break;
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
$l = $this->list_dir($sub_list[$i][$j]);
if (!$l) return $this->error_occur(0x0003, $sub_list[$i][$j]);
$l = $l["list"];
for ($m=0,$n=count($l);$m<$n;$m++) {
$o = $l[$m]["locate"].$l[$m]["name"];
if ($o==$this->last_exist_dir) continue;
$p = str_replace(substr($src_path, 0, -1), $dst_path, $o);
if ($l[$m]["type"]==0) {
$sub_list[$i+1][] = $o;
if (!$this->make_dir($p)) return false;
} else {
if ($this->verify_file($o, $p)) continue;
if (!copy($o,$p)||!$this->verify_file($o,$p)) return $this->error_occur(0x0009, $o);
if (!@unlink($o)) return $this->error_occur(0x0004, $o);
}
}
}
}
for($i=count($sub_list)-1;$i>=0;$i--)
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++)
if (strpos($this->last_exist_dir,$sub_list[$i][$j])!==false) continue; // 对移动目标目录的上层目录,不予考虑删除
elseif (!@rmdir($sub_list[$i][$j])) return $this->error_occur(0x0005, $sub_list[$i][$j]);
unset($i, $j, $k, $l, $m, $n, $o, $p, $sub_list);
return true;
} else {
if (!is_readable($src_path)) return $this->error_occur(0x0006, $src_path);
if ($this->verify_file($src_path,$dst_path)) return true;
$i = strrpos($dst_path, "/");
$dst_path = array(substr($dst_path, 0, $i), substr($dst_path, $i+1));
unset($i);
if (!$this->make_dir($dst_path[0])) return false;
$dst_path = implode("/", $dst_path);
if (!copy($src_path,$dst_path)||!$this->verify_file($src_path,$dst_path)) return $this->error_occur(0x0009, $src_path);
if (@unlink($src_path)) return true;
else return $this->error_occur(0x0004, $src_path);
}
}

/**
* @]Error List[=
* 0x0001 指定目录不存在
* 0x0002 指定目录无读取权限
* 0x0003 找不到要删除的对象
* 0x0004 指定文件无删除权限
* 0x0005 指定目录无删除权限
* 0x0006 指定文件无读取权限
* 0x0007 realpath() 方法参数错误
* 0x0008 指定目录无法创建
* 0x0009 相关文件移动失败
* 0x000A verify_file() 方法参数非文件
* 0x000B 指定文件不存在
* 0x000C 指定文件无写入权限
* 0x000D 指定文件无法锁定
*
*
*
*
*
*/

----------------------------------------END
snakevil 2004-03-28
  • 打赏
  • 举报
回复
2----------------------------------------

/**
* @]Method Name[= delete()
* @]Purpose[=
* 删除指定对象,文件或文件夹——包括内含子目录和文件的非空文件夹
* @]Parameter[=
* string $path 指定要删除的内容路径,文件或目录均可
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function delete($path="") {
if (!file_exists($path)) return $this->error_occur(0x0003, $path);
if (is_dir($path)) {
$path = str_replace("\\", "/", realpath($path));
$path = substr($path, -1)=="/" ? $path : $path."/";
$sub_list = array(array($path));
for ($i=0;$i<count($sub_list);$i++) { // 使用 COUNT($SUB_LIST) 动态判断长度,从而有可能无定长循环
if (!isset($sub_list[$i])) break; // 探索到最尽头,获得该目录下所有子目录列表,方便文件删除后删除目录
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) {
$l = $this->list_dir($sub_list[$i][$j]);
if (!$l) return $this->error_occur("", $sub_list[$i][$j]);
$l = $l["list"];
for ($m=0,$n=count($l);$m<$n;$m++) {
$o = $l[$m]["locate"].$l[$m]["name"];
if ($l[$m]["type"]==0) $sub_list[$i+1][] = $o;
elseif (!@unlink($o)) return $this->error_occur(0x0004, $o); // 删除目录下的每一个文件
}
}
}
for($i=count($sub_list)-1;$i>=0;$i--) // 逆回删除目录
for ($j=0,$k=count($sub_list[$i]);$j<$k;$j++) // 删除每一个子目录直到指定目录
if (!@rmdir($sub_list[$i][$j])) return $this->error_occur(0x0005, $sub_list[$i][$j]);
unset($i, $j, $k, $l, $m, $n, $o, $sub_list);
return true;
} elseif (@unlink($path)) return true;
else return $this->error_occur(0x0004, $path);
}

/**
* @]Method Name[= realpath()
* @]Purpose[=
* 获取现有或不存在文件、目录的绝对地址
* @]Parameter[=
* string $path 要获取地址的文件、目录现有相对、绝对地址
* @]Return[= mixed 错误返回 FALSE,否则为获得的地址
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function realpath($path="") {
if ($path==""||!is_string($path)) return $this->error_occur(0x0007, $path);
$path = preg_replace("/(?<!^\w)[\\\:\*\?\"\<\>\|]/", "", str_replace("\\", "/", $path)); // 规范路径中多可能性的符号
if (substr($path,1,1)==":") return $path; // !!!! Win32 平台的绝对路径
elseif (substr($path,0,1)=="/") return substr(realpath("."), 0, 2).$path; // !!!! Win32 平台下的绝对路径转换
else {
if (substr($path,-1)=="/") $path = substr($path,0,-1); // 清除结尾可能的 / 符号
$path = preg_replace("/\/{2,}/", "/", $path); // 将 /// 诸如类似的相连符号简化为一个
$path = explode("/", $path); // 分割路径
$cur_path = explode("/", str_replace("\\", "/", realpath(".")));
for ($i=0,$j=count($path);$i<$j;$i++) {
if ($path[$i]=="..") array_pop($cur_path);
elseif ($path[$i]=="."||$path[$i]==str_repeat(".", strlen($path[$i]))) continue; // 忽略无用的相对路径地址 . 和 .... 等
else array_push($cur_path, $path[$i]);
}
$path = implode("/", $cur_path);
unset($cur_path);
return $path;
}
}

/**
* @]Method Name[= make_dir()
* @]Purpose[=
* 建立任意文件夹,相对或绝对路径皆可,深层建立亦可
* @]Parameter[=
* string $path 要建立的最终目录路径
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function make_dir($path="") {
if (!$path=$this->realpath($path)) return false;
$path = explode("/", $path);
$i = array($path[0]);
for ($i=0,$j=count($path),$k=array(),$l="";$i<$j;$i++) {
array_push($k, $path[$i]);
$l = implode("/", $k);
if (!file_exists($l)) {
if ($this->last_exist_dir=="") $this->last_exist_dir = $l;
if (!@mkdir($l)) return $this->error_occur(0x0008, $l);
}
}
return true;
}

/**
* @]Method Name[= verify_file()
* @]Purpose[=
* 使用 MD5 算法比较两个文件是否相同
* @]Parameter[=
* string $src 源文件路径
* string $dst 目标文件路径
* boolean $interal 对于超过 1MB 文件,设置 FALSE 省去 MD5 检验步骤,减轻服务器负担
* @]Return[= boolean 错误返回 FALSE,否则 TRUE
* @]Author[= SNakeVil<51JS,BU>(snakevil@qq.com)
* @]See[=
*/
function verify_file($src="",$dst="",$interal=true) {
if (!file_exists($src)||!is_file($src)) return $this->error_occur(0x000A, $src);
if (!file_exists($dst)||!is_file($dst)) return $this->error_occur(0x000A, $dst);
$i = filesize($src);
if ($i!=filesize($dst)) {
unset($i);
return false;
}
if ($i>1024*1024*1024&&!$interal) { // 对于大于 1MB 的文件,如果不要求精确检查,跳过
unset($i);
return true;
}
unset($i);
if (md5_file($src)!=md5_file($dst)) return false;
return true;
}
song213 2004-03-28
  • 打赏
  • 举报
回复
up 一下吧。

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧