Basic operations of file systems
The code is as follows:
Error_reporting (2047 );
/*
* Class I/O (snkedevil completed 03.25.04) (v1.0.0.0)
*
* [Description]
* This class is used to process the file system.
*
* [Function]
* *** List_dir ($ dir_path );
* Reads the content of a specified directory and returns an array of content.
* $ Dir_path: specifies the directory path.
* If an error occurs, FALSE is returned. otherwise, FALSE is returned.
* Array (
* "Count" => array ("files", "dirs", "size "),
* "List" => array (
* Array ("name", "locate", "type", "size", "last_access", "last_change", "last_modify "),
*......
*)
*)
*********
*********
* *** Seek_file ($ pattern, $ dir_path, $ seek_type, $ sub_dir, $ interal, $ limit );
* Search for matched files and directories in the corresponding directory and sub-directories at a given level based on the regular expression conditions.
* $ Pattern is a regular expression that complies with PERL compatibility standards. you do not need to add a regular expression //.
* $ Seek_type has three possible values:-1 0 1, 0 for folders, 1 for files, and-1 for both.
* $ Sub_dir: numeric value. The depth of the subdirectory to be searched. the specified directory is not counted. we recommend that you set the value to 5.
* $ Interal Boolean value. if true, the detailed information of the search result is returned. Otherwise, only the file name, type, and directory are returned.
* $ Limit numeric value and search result limit to avoid excessive waste of system resources
* If an error occurs, FALSE is returned. otherwise, FALSE is returned.
* Array (
* Array (
* "Name", "locate", "type"
* [, "Size", "last_access", "last_change", "last_modify"]
*),
*......
*)
*********
*********
* *** Delete ($ path );
* Delete a specified object, file, or folder, including non-empty folders of the inner directory and file.
* $ Path string, which specifies the path of the content to be deleted, either file or directory
* If an error is interrupted, FALSE is returned; otherwise, TRUE is returned.
*********
*********
* ***** Make_dir ($ path );
* Any folder can be created, either in relative or absolute paths, or in deep layers.
* $ Path string, the final directory path to be created
* If an error occurs, FALSE is returned. otherwise, TRUE is returned.
*********
*********
* *** Verify_file ($ src, $ dst, $ interal );
* Use the MD5 algorithm to compare whether the two files are the same.
* $ Src string, source file path
* $ Dst string, target file path
* $ Interal Boolean value. for files larger than 1 MB, you can set it to FALSE to save MD5 verification steps and reduce server load.
* If an error occurs, FALSE is returned. otherwise, TRUE is returned.
*********
*********
* *** Copy ($ src_path, $ dst_path );
* Any folder or file can be copied with a relative or absolute path. after the file is copied, the system checks whether the error data is correct.
* $ Src_path string, which specifies the path of the source content to be copied, either file or directory
* $ Dst_path: specifies the path of the target content to be copied. the file or directory is optional. the attribute is determined by $ src_path. it can be a lower-level directory of $ src_path.
* If an error occurs, FALSE is returned. otherwise, TRUE is returned.
*********
*********
* *** Move ($ src_path, $ dst_path );
* You can move any folder or file in the relative or absolute path. after the file is moved, the system checks whether the error data is correct.
* $ Src_path string, which specifies the path of the source content to be moved, either file or directory
* $ Dst_path string, which specifies the path of the target content to be moved. the file or directory is optional. the attribute is determined by $ src_path, which can be the lower-level directory of $ src_path.
* If an error occurs, FALSE is returned. otherwise, TRUE is returned.
*
* [Copyright]
* In the Ming and Qing dynasties (snakier @ 51js, and snakier @ BU), the design is complete independently and all power is reserved.
* Use it as needed, but do not retain the following text. thank you!
*
* ============== Z ========================
* Class. IO. v1.0.0.0.build040325
* For. PHP. v4.20 +
* By snail kedevil
* (Snail kedevil @ 51js, snail kedevil @ BU)
* -------- + ------
* QQ: 118824
* MSN: snakevil_@hotmail.com
* HP: http://www.snakevil.com/
* ============== Z ========================
*
*/
Class IO {
Var $ error_id;
Var $ result;
Var $ error_related;
Var $ last_exist_dir;
Function IO (){
$ This-> result = array ();
$ This-> error_id = 0x0000;
$ This-> error_related = "";
$ This-> last_exist_dir = "";
Return $ this;
}
Function error_occur ($ error_id = 0 xffff, $ error_related = "") {// ---- 0xffff ---- an error occurs, but the error cause is unknown
If (is_int ($ error_id) $ this-> error_id = $ error_id; // get the error code
$ This-> error_related = $ error_related;
Return false; // if an error occurs, FALSE is returned for further processing.
}
Function list_dir ($ dir_path = "."){
If (! Is_dir ($ dir_path) return $ this-> error_occur (0x0001, $ dir_path); // ---- 0x0001 ---- the specified directory does not exist
If (! $ Dir_handle = @ opendir ($ dir_path) return $ this-> error_occur (0x0002, $ dir_path); // ---- 0x0002 ---- the specified directory does not have permission to read
$ Result = array (
"Count" => array ("files" => 0, "dirs" => 0, "size" => 0 ),
"List" => array ()
);
While (false! ==( $ File_handle = readdir ($ dir_handle) {// use! = Prevent processing files and directories with names 0 or FALSE
If ($ file_handle = "." | $ file_handle = "..") continue; // ignore two system-specific folders
$ Temp = str_replace ("\", "/", realpath ($ dir_path ));
$ Temp = substr ($ temp,-1) = "/"? $ Temp: $ temp ."/";
$ Temp = array ($ temp, $ file_handle );
$ File_handle = $ temp [0]. $ temp [1]; // Obtain the absolute address
$ 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 ://!!!! For the Win32 platform, content that is neither a file nor a directory is ignored.
$ Temp ["type"] =-1;
}
$ Result ["list"] [] = $ temp;
}
Closedir ($ dir_handle );
Unset ($ dir_handle, $ file_handle, $ temp );
Clearstatcache (); // clear the file system cache
Return $ this-> result = $ result;
}
Function seek_file ($ pattern = ". *", $ dir_path = ".", $ seek_type = 1, $ sub_dir = 0, $ interal = false, $ limit = 100 ){
/* Specify all possible parameter values */
$ 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 ($ dir_path); // treat the query directory as the first layer of the sub-directory hierarchy
$ Result = array ();
/* I the sub-directory level currently processed. 0 indicates the specified directory layer, that is, only one directory is processed */
For ($ I = 0; $ I <= $ sub_dir; $ I ++ ){
If (! Isset ($ sub_dir_list [$ I]) return $ this-> result = $ result; // if a sub-directory is not set in a certain layer, no directory exists in the actual directory system and return
/* K sub-directory statistics at each sub-directory level, j current processing serial number */
For ($ j = 0, $ k = count ($ sub_dir_list [$ I]); $ j <$ k; $ j ++) {// process based on the number of subdirectories in each layer
$ L = $ this-> list_dir ($ sub_dir_list [$ I] [$ j]);
If (! $ L) return $ this-> result = $ result; // if an error occurs, the system immediately stops returning the existing result.
$ L = $ l ["list"];
/* N statistics on files, directories, and other items in each subdirectory. m indicates the current processing sequence number */
For ($ m = 0, $ n = count ($ l); $ m <$ n; $ m ++ ){
If (count ($ result) >=$ limit) return $ this-> result = $ result; // if the required number is reached, return
If ($ l [$ m] ["type"] = 0) $ sub_dir_list [$ I + 1] [] = $ l [$ m] ["locate"]. $ l [$ m] ["name"]; // collects sub-directory information for the next layer.
$ O = $ l [$ m] ["type"];
If ($ o! = $ Seek_type & ($ seek_type = 1 | $ seek_type = 0) continue; // Ignore non-conforming items
Elseif ($ o =-1 & $ seek_type =-1) continue;
If (! Preg_match ($ pattern, $ l [$ m] ["name"]) continue; // ignore items that do not conform to the regular expression
$ 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;
}
Function delete ($ path = ""){
If (! File_exists ($ path) return $ this-> error_occur (0x0003, $ path); // ---- 0x0003 ---- the specified object does not exist
If (is_dir ($ path )){
$ Path = str_replace ("", "/", realpath ($ path ));
$ Path = substr ($ path,-1) = "/"? $ Path: $ path ."/";
$ Sub_list = array ($ path ));
For ($ I = 0; $ I If (! Isset ($ sub_list [$ I]) break; // find the final path to obtain the list of all subdirectories in the directory, so that you can delete the directory after deleting the file.
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); // delete each file in the directory
}
}
}
For ($ I = count ($ sub_list)-1; $ I> = 0; $ I --) // deletes the directory reversely.
For ($ j = 0, $ k = count ($ sub_list [$ I]); $ j <$ k; $ j ++) // delete each subdirectory until the specified directory
If (! @ Rmdir ($ sub_list [$ I] [$ j]) return $ this-> error_occur (0x0005, $ sub_list [$ I] [$ j]); // ---- 0x0005 ---- the directory cannot be deleted
Unset ($ I, $ j, $ k, $ l, $ m, $ n, $ o, $ sub_list );
Return true;
} Elseif (@ unlink ($ path) return true;
Else return $ this-> error_occur (0x0004, $ path); // ---- 0x0004 ---- the file is not authorized to be deleted
}
Function generate_realpath ($ path = ""){
If ($ path = "" |! Is_string ($ path) return $ this-> error_occur (0x0007, $ path); // ---- 0x0007 ---- path Parameter error
$ Path = preg_replace ("/(? |]/"," ", Str_replace (" \ ","/", $ path); // symbol of multiple possibilities in the standard path
If (substr ($ path, 1, 1) = ":") return $ path ;//!!!! Absolute path of Win32 Platform
Elseif (substr ($ path, 0, 1) = "/") return substr (realpath ("."), 0, 2). $ path ;//!!!! Absolute path conversion on Win32 Platform
Else {
If (substr ($ path,-1) = "/") $ path = substr ($ path, 0,-1); // clear possible/symbols at the end
$ Path = preg_replace ("// {2,}/", "/", $ path); // simplify the /// similar concatenation symbol into
$ Path = explode ("/", $ path); // split the 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; // ignore useless relative path addresses. and .... and so on
Else array_push ($ cur_path, $ path [$ I]);
}
$ Path = implode ("/", $ cur_path );
Unset ($ cur_path );
Return $ path;
}
}
Function make_dir ($ path = ""){
If (! $ Path = $ this-> generate_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); // ---- 0x0008 ---- cannot create a directory
}
}
Return true;
}
Function verify_file ($ src = "", $ dst = "", $ interal = true ){
If (! File_exists ($ src) |! Is_file ($ src) return $ this-> error_occur (0x000A, $ src); // ---- 0x000A ---- specifies that the object is not a file
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) {// for files larger than 1 MB, skip
Unset ($ I );
Return true;
}
Unset ($ I );
If (md5_file ($ src )! = Md5_file ($ dst) return false;
Return true;
}
Function copy ($ src_path = "", $ dst_path = ""){
If (! File_exists ($ src_path) return $ this-> error (0x0003, $ src_path );
If (! $ Dst_path = $ this-> generate_realpath ($ dst_path) return false;
If (is_dir ($ src_path )){
$ This-> last_exist_dir = ""; // record the existing directory
If (! $ This-> make_dir ($ dst_path) return false; // directory creation failed
$ Src_path = str_replace ("", "/", realpath ($ src_path ));
$ Src_path = substr ($ src_path,-1) = "/"? $ Src_path: $ src_path ."/";
$ Sub_list = array ($ src_path ));
For ($ I = 0; $ 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; // if the parent directory is copied to a lower-level directory, it prevents endless loops.
$ 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; // create each subdirectory
} Else {// Copy each file
If ($ this-> verify_file ($ o, $ p) continue; // if the target is exactly the same as the source, no replication is performed.
If (! Copy ($ o, $ p) |! $ This-> verify_file ($ o, $ p) return $ this-> error_occur (0x0009, $ o); // ---- 0x0009 ---- file moving failed
}
}
}
}
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); // ---- 0x0006 ---- the source file has no permission to read
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;
}
}
Function move ($ src_path = "", $ dst_path = ""){
If (! File_exists ($ src_path) return $ this-> error (0x0003, $ src_path );
If (! $ Dst_path = $ this-> generate_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 ($ src_path ));
For ($ I = 0; $ 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; // The Upper Directory of the target directory is not deleted.
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 (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 );
}
}
}
?>