文件系统处理包括文件和目录的新建、复制、移动、删除等操作。在开发前我们要确认脚本对某个文件和目录有相应的文件系统的读写权限,包括安全模式及Apache或Nginx的权限设置,以保证PHP对文件的操作正确性。
fopen()函数会把操作的文件句柄放在文件头,如代码清单1-37所示:
代码清单1-37 文件打开的几种方式
//打开Linux系统下的文件 $handle = fopen("/var/logs/somefile.txt", "r"); // 打开Windows系统下的文件 $handle = fopen("c:/data/info.txt", "rt"); $handle = fopen("c:/data/info.txt", "rt");
PHP能提供几种打开文件的方法和模式,具体取决于我们想用它做什么。如果处理已经存在的文件,也不想删除它原来的内容,可用下面两种模式。
·R-:以只读方式打开该文件,将游标置于文件头。
·R+-:打开文件进行读取和写入,将游标置于文件头。
如果想新创建一个文件或替换现有文件,可使用以下两种模式之一。参数说明如下:
·W-:打开文件,将光标置于文件头,如果该文件存在,将清空它的内容(零长度截断该文件),如文件不存在,它将尝试创建。
·W+-:同上,这一次的打开文件进行读也一样。
PHP允许我们使用两种追加写入文件的模式。参数说明如下:
·a-:追加模式。打开文件,如果文件有内容,则从末尾追加写(读)。如果该文件不存在,则尝试创建它。
·a+-:追加模式。打开文件,游标置于文件尾部,将从文件末尾开始追加(写),如果该文件不存在,则尝试创建它。
以下两个模式,称为谨慎的文件写操作:
·X-:写模式打开文件。从文件头开始写,如果文件已经存在,该文件将不会被打开,fopen()将返回FALSE,PHP也会产生警告。
·X+-:读/写模式打开文件。功能和X-相同。
当基于Windows的操作系统上的文件处理时有两个模式,开发者需要了解一些参数的处理。
·t:当前处理的文本文件的行结束符(\r\n)。
·b:如果处理的是非文本文件,建议使用b标志;如果不这样,在Windows系统打开文件时,可能会遇到一些奇怪的问题,因此开始需要使用此模式。
下面我们将专注说明读取文本文件的几个方法。
大多的读取文件场景,都是读取文件的每一行后进行操作。这时可以使用file()函数读取整个文件到一个数组中,如代码清单1-38所示:
代码清单1-38 使用file函数打开文件
$lines = file("/tmp/files/InputTextFile.txt"); foreach ($lines as $line_num => $line) { echo "Line #{$line_num} : " . $line . "n"; }
我们还可以添加file()函数支持的可选参数:
·FILE_USE_INCLUDE_PATH-在include_path包含路径中查找相关文件。
·FILE_IGNORE_NEW_LINES-不能在每个数组元素的最后添加新行(在这里是$line)。
·FILE_SKIP_EMPTY_LINES-跳过空行,这在删除文件中多余空行时很有用。
file_get_contents()函数可以一次读取文件的全部内容,它接受两个额外参数时很有用,分别是offset和MAXLEN(PHP 5.1以上支持),offset偏移指定从哪里开始读取,MAXLEN指定从源文件读取的字节数。
下面的代码表示从第128字节开始读取,读取1KB的数据内容,如代码清单1-39所示:
代码清单1-39 分段读取文件
$file = file_get_contents("/tmp/files/InputTextFile.txt",0,null,128,1024); echo $file;
可以使用file_get_contents()函数读取远端URL的文件内容,如代码清单1-40所示:
代码清单1-40 读取远端URL文件
$file= file_get_contents("http://www.21cto.com/files/InputTextFile.txt"); echo $file;
还可以联合使用file_get_contents()和file_put_contents()函数,它接受一个连续的内容作为参数,并一次写入文件里,如代码清单1-41所示:
代码清单1-41 读取文件和写入文件
//某图片的url地址 $url="http://www.21cto.com/assets/images/logo.png"; //读取二进制“字符串” $data=file_get_contents($url); //要写入的目标文件和路径 $filepath = "/usr/local/www/images/upload/upload.jpg"; //保存 file_put_contents($filepath,$data)or die("不能写入文件");
我们可以使用这两个函数很方便地抓取远端文件,如HTML页面或图片等资源。还有更直接的方式来取得缓冲区中的文件内容,使用readfile()函数可以做到这一点。我们甚至不需要做更多的处理,它已返回已读取的字节数,如代码清单1-42所示:
代码清单1-42 使用readfile()函数获取文件的大小
<?php // 使用readfile() $file = "/tmp/files/InputTextFile.txt"; $bytesRead = readfile($file); echo $bytesRead; ?>
fgets()函数可以帮我们读取文件时从文件指针的位置开始读取一行,并作为一个字符串返回,也可以指定想让它读取的字节长度。在下面的例子中,我们想读取文件中的8KB字节。具体如代码清单1-43所示:
代码清单1-43 指定读取文件的长度
<?php $file = "c:/tmp/files/InputTextFile.txt"; $handle = fopen($file, "rt"); if ($handle) { while (!feof($handle)) { $buffer = fgets($handle, 8192); echo $buffer; } fclose($handle); }?>
最后一个函数,我们看一下如何使用fread()函数,它主要用来读取二进制文件。它需要一个文件句柄和文件指针读取字节的长度。读取文件结束时,当文件或网络数据包(流)被读取到8192个字节(8 KB),或者已经到文件尾(EOF)时,读取结果。具体如代码清单1-44所示:
代码清单1-44 fread()——安全读取二进制文件
<?php $file = "/tmp/files/picture.gif"; // 如果是Windows系统用"rb" $handle = fopen($file, "r"); $contents = fread($handle, filesize($file)); fclose($handle); ?>
下面的代码是如何从一个网址读取一个二进制文件。如代码清单1-45所示:
代码清单1-45 安全读取远端二进制文件
<?php $handle = fopen("http://www.21cto.com/picture.gif", "r"); $contents = ''; while (!feof($handle)) { $contents = $contents.fread($handle, 8192); } fclose($handle); ?>