入门 - 常见文件操作

  • 作者:KK

  • 发表日期:2016.12.21


有时候我们还需要用PHP代码去读取文件、生成数据文件,本文章针对最常见的使用函数作一个介绍


scandir获取目录下所有文件

$files = scandir('D:');
print_r($files);

其中目录也会列出来,因为目录其实也是一种文件


file_exists判断一个路径是否存在

if(file_exists('E:/a.txt')){
	echo 'a.txt存在';
}else{
	echo '说好的txt呢?';
}
  • 重要知识点:如果路径是一个目录,也会认为存在,别以为这个函数开头有file字节就以为只判断我们平时接触的文件,其实目录也是个文件!
if(file_exists('C:/Windows')){
	echo 'Windows系统目录存在';
}else{
	echo '你的Windows系统没装C盘?';
}

判断文件是否存在要用is_file

如果你不想判断目录,只想判断就这样:

if(is_file('C:/Windows')){
	echo '这是个文件';
}else{
	echo '这是个目录';
}

is_dir判断是否为目录

if(is_dir('C:/Windows')){
	echo '这是个目录';
}else{
	echo '这是个文件';
}

删除文件

unlink('D:/a/b/c.txt');

unlink('b.txt');

如果文件不存在的话会报错的哦


重命名|移动文件

rename('D:/a.txt', 'D:/b.txt'); // 新的文件名就是个完整路径

rename('D:/a.txt', 'D:/b/c/a.txt'); // 这个路径可以跟原路径不在同一目录,实现移动文件

目录创建与删除

mkdir(__DIR__ . '/xxx'); //在当前目录下创建一个xxx文件夹,用相对路径也可以

rmdir(__DIR__ . '/xxx'); //删除掉

rmdir(__DIR__); // 删除当前目录,会报错,因为这个目录不是空的,rmdir只能删除空目录,所以要先删除里面所有文件和文件夹,让它变成空才可以

判断目录|文件是否能读写

有些目录|文件是不允许读取里面的文件列表或者往里面写文件的

print_r([
	is_readable('C:\Windows\System32'), //判断是否可读

	is_writeable('C:\Windows\System32'), //判断是否可写
]);

关于这两个函数通常在起初做程序时新手都不会注意使用到,也不知该什么时候使用

可能需要遇到程序问题时,比如读不到文件或写不入文件报错时才会增加判断,而且开发时感知不到这种问题,是程序放到Linux系统上运行了才容易碰到

Windows系统也会有这种问题,只是比较少人把正式程序跑在Windows上,先记一下这两个函数,以后记得有这种功能做判断回来找就好


快速读写文件

这个不重复了,在写文件读文件里介绍过,分别就是file_get_contents($file)file_put_contents($file, $content)


获取文件的大小

filesize函数,例如下面输出当前工作目录的index.php的文件大小

$size = filesize('index.php');
echo '一共是 ' . $size . 'B(字节)'; //一个字母数字符号就一个字节,中文根据编码不同2~3个字节
echo '就是 ' . intval($size / 1024) . 'KB,不足4KB的话系统会分配4KB';

完整写文件

在大并发应用、高性能要求的情况下需要用这些函数,平时快速读写就不需要了

$file = 'E:/a.txt';
$mode = 'w';
$fileHandler = fopen($file, $mode); //用w模式打开一个文件,并返回一个文件句柄,w模式的作用是写文件
fwrite($fileHandler, 'abcdefg'); //向$fileHandler这个句柄写入abcdefg
fclose($fileHandler); //释放句柄

这是一个完整的写文件过程,如果E:/a.txt根本不存在,则会自动创建

  1. 先通过fopen得到一个文件句柄,但必须指定一个模式,这里我演示的是w模式(write)

  2. 通过fwrite向指定的句柄写入内容

  3. fclose关闭句柄(如果不关闭,则其它进程无法再操作这个文件,就是在windows下偶尔遇到的提示文件被占用,要fclose后才能解除占用)


完整读文件

和写文件的流程一样,不过模式要用r模式(r = read),测试代码:

$fileHandler = fopen('E:/a.txt', 'r');
$content = fread($fileHandler, 4); //读取句柄相关文件的4个字节内容
fclose($fileHandler);

echo $content; //假设内容是abcdefg,那读出的就是abcd四个字母了

可是这不是有点为难人吗,fread函数读文件时还要指定要读多少字节,我们怎么知道要读取的文件到底有多少字节呀?

就算知道了,写1000字节吧,但过一会它没准又会被别人修改了内容,不是1000字节了呢!

办法就是通过filesize函数取得文件的字节数,再把这个数字传进去fread($fileHandler, filesize('E:/a.txt'))

好了你一定想着如果这么折腾不如直接file_get_contents


以上内容其实都能用file_get_contents和file_put_contents来取代实现简化的代码

可是fopen、fclose这些的存在并不是多余的,一般来说要这样用的话,都会匹配文件锁来用

之所以有文件锁的存在是因为大并发的情况下可能会有多个进程|线程同时操作同一个文件,为了保证自己操作完后才让别人操作,就有了“让我锁住这个文件不让别人动”的实现需求

可是基础阶段讲这个不实用,还干扰了新手学习,进阶的时候再说

这里主要是认识一下完整的读写文件,因为平时阅读别人的代码(特别是开源代码)会遇到这些具体的文件操作过程,这样可以快速明白别人的代码在干嘛


文件模式

如果fopen的时候第2个mode参数只用了r模式,那执行fwrite的话会报错的,因为r是只读模式

其实文件模式有很多种,我也不一一细说,其实新手真的一般用不上啦,下面是一个r+(读写)模式的例子:

$fileHandler = fopen('E:/a.txt', 'r+');
echo fread($fileHandler, 4); //读出该文件原有的前4个字节

fwrite($fileHandler, 'abcdefg'); //写入内容

echo fread($fileHandler, 4); //如果已经有写入,那再读就会空了
fclose($fileHandler);

更多文件模式就不一一讲解了,有兴趣请自己去官网查询PHP 手册 函数参考 文件系统相关扩展 Filesystem Filesystem 函数