PHP强化之12 - 文件及目录操作
一、目录操作
1、目录句柄
1)打开目录句柄
resource opendir ( string $path [, resource $context ] )
打开一个目录句柄,可用于之后的 closedir(),readdir() 和 rewinddir() 调用中。如果成功则返回目录句柄的 resource,失败则返回 FALSE。
2)从目录句柄中读取条目
string readdir ([ resource $dir_handle ] )
返回目录中下一个文件的文件名。文件名以在文件系统中的排序返回。成功则返回文件名 或者在失败时返回 FALSE。
3)关闭目录句柄
void closedir ([ resource $dir_handle ] )
关闭由 dir_handle 指定的目录流。流必须之前被 opendir() 所打开。
2、列出指定路径中的文件和目录
array scandir ( string $directory [, int $sorting_order [, resource $context ]] )
返回一个 array,包含有 directory 中的文件和目录。
注意:
1)但不包子级。
2)'.'与'..'也会被返回。
优点:不需要创建目录句柄。
3、新建与删除目录
1)新建目录
bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false [, resource $context ]]] )
默认的 mode 是 0777,意味着最大可能的访问权。
2)删除目录
bool rmdir ( string $dirname [, resource $context ] )
尝试删除 dirname 所指定的目录。 该目录必须是空的,而且要有相应的权限。 失败时会产生一个 E_WARNING 级别的错误。
4、其它函数
1) 判断是否是目录
bool is_dir ( string $filename )
判断给定文件名是否是一个目录。
如果文件名存在并且为目录则返回 TRUE。如果 filename 是一个相对路径,则按照当前工作目录检查其相对路径。
2)取得当前工作目录
string getcwd ( void )
成功则返回当前工作目录,失败返回 FALSE。如果 directory 不是个目录,则返回布尔值 FALSE 并生成一条 E_WARNING 级的错误。
在某些 Unix 的变种下,如果任何父目录没有设定可读或搜索模式,即使当前目录设定了,getcwd() 还是会返回 FALSE。
二、 文件操作
1、文件指针
1)打开文件或者URL资源
resource fopen ( string $filename , string $mode [, bool $use_include_path = false [, resource $context ]] )
mode常用参数:
mode | 说明 |
---|---|
'r' | 只读方式打开,将文件指针指向文件头;该文件必须存在。 |
'r+' | 读写方式打开,将文件指针指向文件头;该文件必须存在。 |
'w' | 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 |
'w+' | 读写方式打开,其他的行为和 'w' 一样。 |
'a' | 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。 |
'a+' | 读写方式打开,其他的行为和 'a' 一样。 |
'x' | 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回 FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。 |
'x+' | 创建并以读写方式打开,其他的行为和 'x' 一样。 |
Windows 下提供了一个文本转换标记('t')可以透明地将 \n 转换为 \r\n。与此对应还可以使用 'b' 来强制使用二进制模式,这样就不会转换数据。要使用这些标记,要么用 'b' 或者用 't' 作为 mode 参数的最后一个字符。(不建议使用t)
2)读取文件
string fread ( resource $handle , int $length )
fread() 从文件指针 handle 读取最多 length 个字节。 该函数在遇上以下情况时停止读取文件:
-- 读取了 length 个字节
-- 到达了文件末尾(EOF)
注意:是从文件指针的指针处开始读取,并不一定是文件开头。
3)写入文件
int fwrite ( resource $handle , string $string [, int $length ] )
fwrite() 把 string 的内容写入 文件指针 handle 处。
fputs()
为fwrite()
的别名。
4)关闭文件
bool fclose ( resource $handle )
handle文件指针必须有效,并且是通过 fopen() 或 fsockopen() 成功打开的。
5)倒回文件指针的位置
bool rewind ( resource $handle )
将 handle 的文件位置指针设为文件流的开头。
如果将文件以附加("a" 或者 "a+")模式打开,写入文件的任何数据总是会被附加在后面,不管文件指针的位置。
6)测试文件指针是否到了文件结束的位置
bool feof ( resource $handle )
如果文件指针到了 EOF 或者出错时则返回 TRUE,否则返回一个错误(包括 socket 超时),其它情况则返回 FALSE。
7)例子
//在文件的头部插入一段字符串:
$file = './demo_text1.txt';
$h = fopen($file,'r');
$content = fread($h,filesize($file));
$text = "Hi , nosee! \n".$content;
fclose($h);
$h = fopen($file,'w');
fwrite($h,$text);
fclose($h);
2、不需要fopen打开的函数
1)file_get_contents
string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )
file_get_contents() 函数是用来将文件的内容读入到一个字符串中的首选方法。如果操作系统支持还会使用内存映射技术来增强性能。
2)file_put_contents
int file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] )
将一个字符串写入文件。
注意:当flags的值为
FILE_APPEND
时,表示如果文件 filename 已经存在,则追加数据而不是覆盖。
3)file
array file ( string $filename [, int $flags = 0 [, resource $context ]] )
把整个文件读入一个数组中。
可选参数 flags 可以是以下一个或多个常量:
-- FILE_USE_INCLUDE_PATH 在 include_path 中查找文件。
-- FILE_IGNORE_NEW_LINES 在数组每个元素的末尾不要添加换行符
-- FILE_SKIP_EMPTY_LINES 跳过空行
4)readfile
int readfile ( string $filename [, bool $use_include_path = false [, resource $context ]] )
读取文件并写入到输出缓冲。
3、文件信息
1)文件大小
int filesize ( string $filename )
返回文件大小的字节数。如果出错返回 FALSE 并生成一条 E_WARNING 级的错误。
2)文件的类型
string filetype ( string $filename )
返回文件的类型。 可能的值有 fifo,char,dir,block,link,file 和 unknown。
3)文件路径的信息
mixed pathinfo ( string $path [, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME ] )
pathinfo返回一个关联数组包含有 path 的信息。返回关联数组还是字符串取决于 options。
如果没有传入 options ,将会返回包括以下单元的数组:
array:dirname,basename 和 extension(如果有),以 及filename。
4)文件的时间
int filemtime ( string $filename )
返回文件中的数据块上次被写入的时间,也就是说,文件的内容上次被修改的时间。
int fileatime ( string $filename )
取得文件的上次访问时间。
int filectime ( string $filename )
取得文件的 inode 修改时间。(Note:注意某些 Unix 说明文本中把 ctime 说成是该文件建立的时间,这是错的。在大多数 Unix 文件系统中没有 Unix 文件的建立时间。)
5)删除文件
bool unlink ( string $filename [, resource $context ] )
删除 filename。和 Unix C 的 unlink() 函数相似。
三、其它函数
1)拷贝文件
bool copy ( string $source , string $dest [, resource $context ] )
将文件从 source 拷贝到 dest。如果要移动文件的话,请使用 rename() 函数。
2)重命名文件或目录
bool rename ( string $oldname , string $newname [, resource $context ] )
尝试把 oldname 重命名为 newname。
3)检查文件或目录是否存在
bool file_exists ( string $filename )
4)判断文件名权限
判断给定文件名是否存在并且可读:
bool is_readable ( string $filename )
判断给定的文件名是否可写:
bool is_writable ( string $filename )
如果文件存在并且可写则返回 TRUE。filename 参数可以是一个允许进行是否可写检查的目录名。
判断给定文件名是否可执行:
bool is_executable ( string $filename )
四、经典实例
1、列出一个目录里的所有文件及目录(包括子目录里面的)
$dir = '/var/www/html';
function loop_dir($dir){
$handle = opendir($dir);
if ($handle) {
while (false !== ($file = readdir($handle))) {
if($file != '.' && $file != '..'){
echo "$file \n";
if(filetype($dir.'/'.$file) == 'dir'){
loop_dir($dir.'/'.$file);
}
}
}
}
}
loop_dir($dir);
closedir();
或者可以使用scandir函数:
$dir = '/var/www/html';
function loop_dir($dir){
static $array = [];
$dir_arr = scandir($dir);
if ($dir_arr) {
foreach($dir_arr as $val){
if($val != '.' && $val != '..'){
if(filetype($dir.'/'.$val) == 'dir'){
$array[] = substr($dir.'/'.$val.'/',14);
loop_dir($dir.'/'.$val);
}else{
$array[] = substr($dir.'/'.$val,14);
}
}
}
}
return $array;
}
$a = loop_dir($dir);
var_dump($a);
返回结果如下:
array (size=10)
0 => string '.demo21.php.swp' (length=15)
1 => string 'aaa/' (length=4)
2 => string 'aaa/a1/' (length=7)
3 => string 'aaa/a2/' (length=7)
4 => string 'aaa/a3/' (length=7)
5 => string 'bbb/' (length=4)
6 => string 'demo20.php' (length=10)
7 => string 'demo21.php' (length=10)
8 => string 'demo_text1.txt' (length=14)
9 => string 'index.html' (length=10)
2、大文件读取方法
$fp = fopen($filename,'r');
$buffer = 2048;
while(!feof($fp)){
$str = fread($fp,$buffer);
//$str = str_replace("\r\n","<br />",$str);//换行符转换
echo $str;
}
fclose($fp);
参考
官方手册:
http://php.net/manual/zh/ref.filesystem.php
http://php.net/manual/zh/ref.dir.php