php的fread 读取整个文件()把文件读到哪里了?

没有更多推荐了,
不良信息举报
举报内容:
php读取文件fopen(),feof(),fread(),fgets(),fclose()全套
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!本文出自汗血宝马,转载时请注明出处及相应链接。
本文永久链接: http://www.caotama.com/103101.html
Ɣ回顶部博客分类:
对于一般的web应用程序,数据会保存在数据库表中,但是文件操作也是必须的,例如文件的读取、写入等,典型的应用场景是考试报名,当系统启动时,自动读取“报名须知”的内容到内存中,然后再需要时显示到页面当中。这次本文
将研究一下PHP中的文件操作。
1. 读取文件到数组(file)
file()函数可以将文件按行读取到一个字符串数组中,后续程序可以通过遍历这个字符串数组来做处理。
file:file.php
url:http://localhost:88/file/file.php
$file = file(basename(__FILE__));
$lines = count($file);
for($i=0; $i&$ $i++){
$color = ($i%2==0) ? 'red' : 'white';
echo '&div style="background-color: '.$color.'"&';
echo $i.':'.htmlspecialchars($file[$i]);
echo '&/div&';
2. 读取文件到字符串(file_get_contents)
file_get_contents()函数可以将文件中的所有内容读取到一个字符串变量中,后续程序可以将这个字符串中的内容显示在页面,或者写入到新文件当中。
file:file_get_contents.php
url:http://localhost:88/file/readfile.php
$file = file_get_contents('file.html');
$file = strip_tags($file);
echo '&form&&textarea rows=12 cols=80&'.htmlspecialchars($file).'&/textarea&&/form&';
3. 读取文件到屏幕(readfile)
readfile()函数直接读取文件内容并回显到屏幕,上传或下载时也会用到这个函数。
file:readfile.php
url:http://localhost:88/file/readfile.php
readfile('file.html');
上面的方法只能全部或按照新行符读取文件中的内容,读到数组或字符串或屏幕中,然后如果需要更加灵活的读取文件内容或写文件内容,就需要用到文件句柄了,类似于C语言当中的文件读写函数。
4. 一次读取整个文件内容(fread、filesize)
对于文件的大小相对比较小的文件,可以一次将整个文件的内容读取到内存当中。步骤是,1)fopen打开新文件,并指定使用模式,2)使用fread按照指定的长度读取文件内容,3)fclose关闭句柄。
file:fread.php
url:http://localhost:88/file/fread.php
$location = 'file.html';
$file = fopen($location, "rb");
$fileContent = fread($file, filesize($location));
fclose($file);
echo $fileC
5. 分次读取整个文件的内容(fgets、feof)
fgets函数可以分片获取文件的中内容,feof可以判断文件是否已经读取到末尾。
file:fgets.php
url:http://localhost:88/file/fgets.php
$location = 'file.html';
$fp = fopen($location, 'rb');
while(!feof($fp)){
$chunk = fgets($fp);
fclose($fp);
6. 一次读取(file_get_contents),一次写入(file_put_contents)
有时候对于小文件读取和写入,可以方便的使用file_get_contents()和file_put_contents()方法进行写入,无需创建文件句柄。
file:readOnce_writeOnce.php
url:http://localhost:88/file/readOnce_writeOnce.php
$source = 'file.html';
$destination1 = 'readOnce_writeOnce.html';
// 一次读取,一次写入
$sourceContent = file_get_contents($source);
file_put_contents($destination1, $sourceContent);
7. 分行读取,分行写入(fwrite)
对于大文件的读取和写入,如果一次load到内容,很有可能导致内存溢出或web服务器宕机,因此需要采用逐行读取逐行写入。可以使用file()行数将源文件读取到一个字符串数组中,然后通过fwrite逐行写入目标文件,当然,需要使用fopen打开句柄,写入结束后使用fclose关闭句柄。
file:multiRead_multiWrite.php
url:http://localhost:88/file/multiRead_multiWrite.php
$source = 'file.html';
$destination2 = 'multiRead_multiWrite.html';
$lines = file($source);
$fp = fopen($destination2, 'w');
foreach ($lines as $line) {
fwrite($fp, $line);
fclose($fp);
8. 其他文件处理函数
file:other.php
url:http://localhost:88/file/other.php
$fileName = basename(__FILE__);
$dirPath = './';
// file_exists()返回1 或 0
echo $fileName.': '.file_exists($fileName).'&br/&';
// is_file()返回1 或 0
echo $fileName.' is '.is_file($fileName)?'file':'directory'.'!'.'&br/&';
// is_readable()返回1 或 0
echo $fileName.' readable:'.is_readable($fileName).'&br/&';
// is_writable()返回1 或 0
echo $fileName.' writable:'.is_writable($fileName).'&br/&';
echo $fileName.' created at:'.filemtime($fileName).'&br/&';
echo $fileName.' created at:'.fileatime($fileName).'&br/&';
echo $fileName.' size:'.filesize($fileName).'&br/&';
9. 目录读取(opendire、readdir、closedir)
第一种方法,使用opendir、readdir、closedir函数进行目录的打开、读取、关闭,类似于文件的fopen、fread、fclose,代码如下:
file:dir.php
url:http://localhost:88/file/dir.php
$location = './';
$dp = opendir($location);
while ($entry = readdir($dp)){
if(is_dir($entry))
echo '[DIR] '.$entry. '&br/&';
}elseif (is_file($entry))
echo '[FILE] '.$entry. '&br/&';
closedir($dp);
第二种方法,采用php提供的面向对象的dir类,通过传入一个目录路径来构造一个dir实例,再通过实例的read方法进行目录读取,代码如下:
file:dir-class.php
url:http://localhost:88/file/dir-class.php
$location = './';
$dir = dir($location);
while ($entry = $dir-&read()){
if(is_dir($entry))
echo '[DIR] '.$entry. '&br/&';
}elseif (is_file($entry))
echo '[FILE] '.$entry. '&br/&';
closedir($dp);
10. 文件拷贝(copy)
file:copy.php
url:http://localhost:88/file/copy.php
$source = 'file.html';
$dest = 'file-copy.html';
copy($source, $dest);
11. 文件移动、重命名(rename)
$source = 'file-copy.html';
$dest = 'file-copy-1.html';
rename($source, $dest);
本文地址:http://ryan-d.iteye.com/blog/1543374
下载次数: 7
浏览: 53054 次
来自: 广州
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
$fp = fopen ( "/tmp/lock.txt", "w+" );
if (flock ( $fp, LOCK_EX )) {
fwrite ( $fp, "Write something here\n" );
flock ( $fp, LOCK_UN );
echo "Couldn't lock the file !";
fclose ( $fp );
但在PHP中,flock似乎工作的不是那么好!在多并发情况下,似乎是经常独占资源,不即时释放,或者是根本不释放,造成死锁,从而使服务器的cpu占用很高,甚至有时候会让服务器彻底死掉。好像在很多linux/unix系统中,都会有这样的情况发生。所以使用flock之前,一定要慎重考虑。那么就没有解决方案了吗?其实也不是这样的。如果flock()我们使用得当,完全可能解决死锁的问题。当然如果不考虑使用flock()函数,也同样会有很好的解决方案来解决我们的问题。经过我个人的搜集和总结,大致归纳了解决方案有如下几种。方案一:对文件进行加锁时,设置一个超时时间.
if ($fp = fopen ( $fileName, 'a' )) {
$startTime = microtime ();
$canWrite = flock ( $fp, LOCK_EX );
if (! $canWrite)
usleep ( round ( rand ( 0, 100 ) * 1000 ) );
} while ( (! $canWrite) && ((microtime () - $startTime) & 1000) );
if ($canWrite) {
fwrite ( $fp, $dataToSave );
fclose ( $fp );
超时设置为1ms,如果这里时间内没有获得锁,就反复获得,直接获得到对文件操作权为止,当然。如果超时限制已到,就必需马上退出,让出锁让其它进程来进行操作。方案二:不使用flock函数,借用临时文件来解决读写冲突的问题。大致原理如下:1。将需要更新的文件考虑一份到我们的临时文件目录,将文件最后修改时间保存到一个变量,并为这个临时文件取一个随机的,不容易重复的文件名。2。当对这个临时文件进行更新后,再检测原文件的最后更新时间和先前所保存的时间是否一致。3。如果最后一次修改时间一致,就将所修改的临时文件重命名到原文件,为了确保文件状态同步更新,所以需要清除一下文件状态。4。但是,如果最后一次修改时间和先前所保存的一致,这说明在这期间,原文件已经被修改过,这时,需要把临时文件删除,然后返回false,说明文件这时有其它进程在进行操作。大致实现代码如下:
$dir_fileopen = "tmp";
function randomid() {
return time () . substr ( md5 ( microtime () ), 0, rand ( 5, 12 ) );
function cfopen($filename, $mode) {
global $dir_fileopen;
clearstatcache ();
$id = md5 ( randomid ( rand (), TRUE ) );
$tempfilename = $dir_fileopen . "/" . $id . md5 ( $filename );
} while ( file_exists ( $tempfilename ) );
if (file_exists ( $filename )) {
$newfile = false;
copy ( $filename, $tempfilename );
$newfile = true;
$fp = fopen ( $tempfilename, $mode );
return $fp ? array ($fp, $filename, $id, @filemtime ( $filename ) ) : false;
function cfwrite($fp, $string) {
return fwrite ( $fp [0], $string );
function cfclose($fp, $debug = "off") {
global $dir_fileopen;
$success = fclose ( $fp [0] );
clearstatcache ();
$tempfilename = $dir_fileopen . "/" . $fp [2] . md5 ( $fp [1] );
if ((@filemtime ( $fp [1] ) == $fp [3]) || ($fp [4] == true && ! file_exists ( $fp [1] )) || $fp [5] == true) {
rename ( $tempfilename, $fp [1] );
unlink ( $tempfilename );
//说明有其它进程 在操作目标文件,当前进程被拒绝
$success = false;
return $success;
$fp = cfopen ( 'lock.txt', 'a+' );
cfwrite ( $fp, "welcome to beijing.\n" );
fclose ( $fp, 'on' );
对于上面的代码所使用的函数,需要说明一下:1.rename();重命名一个文件或一个目录,该函数其实更像linux里的mv。更新文件或者目录的路径或名字很方便。但当我在window测试上面代码时,如果新文件名已经存在,会给出一个notice,说当前文件已经存在。但在linux下工作的很好。2.clearstatcache();清除文件的状态.php将缓存所有文件属性信息,以提供更高的性能,但有时,多进程在对文件进行删除或者更新操作时,php没来得及更新缓存里的文件属性,容易导致访问到最后更新时间不是真实的数据。所以这里需要使用该函数对已保存的缓存进行清除。
方案三:对操作的文件进行随机读写,以降低并发的可能性。在对用户访问日志进行记录时,这种方案似乎被采用的比较多。先前需要定义一个随机空间,空间越大,并发的的可能性就越小,这里假设随机读写空间为[1-500],那么我们的日志文件的分布就为log1~到log500不等。每一次用户访问,都将数据随机写到log1~log500之间的任一文件。在同一时刻,有2个进程进行记录日志,A进程可能是更新的log32文件,而B进程呢?则此时更新的可能就为log399.要知道,如果要让B进程也操作log32,概率基本上为1/500,差不多约等于零。在需要对访问日志进行分析时,这里我们只需要先将这些日志合并,再进行分析即可。使用这种方案来记录日志的一个好处时,进程操作排队的可能性比较小,可以使进程很迅速的完成每一次操作。
方案四:将所有要操作的进程放入一个队列中。然后专门放一个服务完成文件操作。队列中的每一个排除的进程相当于第一个具体的操作,所以第一次我们的服务只需要从队列中取得相当于具体操作事项就可以了,如果这里还有大量的文件操作进程,没关系,排到我们的队列后面即可,只要愿意排,队列的多长都没关系。
对于以前几种方案,各有各的好处!大致可能归纳为两类:1。需要排队(影响慢)比如方案一、二、四2。不需要排队。(影响快)方案三在设计缓存系统时,一般我们不会采用方案三。因为方案三的分析程序和写入程序是不同步的,在写的时间,完全不考虑到时候分析的难度,只管写的行了。试想一下,如我们在更新一个缓存时,如果也采用随机文件读写法,那么在读缓存时似乎会增加很多流程。但采取方案一、二就完全不一样,虽然写的时间需要等待(当获取锁不成功时,会反复获取),但读文件是很方便的。添加缓存的目的就是要减少数据读取瓶颈,从而提高系统性能。
从上为个人经验和一些资料的总结,有什么不对的地方,或者没有谈到的地方,欢迎各位同学指正。
阅读(3106)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'php高并发状态下文件的读写(fopen,fwrite,fread)',
blogAbstract:'对于日IP不高或者说并发数不是很大的应用,一般不用考虑这些!!用一般的文件操作方法完全没有问题。但如果并发高,在我们对文件进行读写操作时,很有可能多个进程对进一文件进行操作,如果这时不对文件的访问进行相应的独占,就容易造成数据丢失。例如:一个在线聊天室(这里假定把聊天内容写入文件),在同一时刻,用户A和用户B都要操作数据保存文件,首先是A打开了文件,然后更新里面的数据,但这里B也正好也打开了同一个文件,也准备更新里面的数据。当A把写好的文件保存时,这里其实B已经打开了文件。但当B再把文件保存回去时,这里已经造成了数据的丢失,因为这里B用户完全不知道它所打开的文件在它对其进行更改时,A用户也更改了这个文件,所以最后B用户保存更改时,用户A的更新就被会丢失。对于这样的问题,一般的解决方案时当一进程对文件进行操作时,首先对其它进行加锁,意味着这里只有该进程有权对文件进行读取,其它进程如果现',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:9,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 php fread 逐行读取 的文章

 

随机推荐