当前位置: 首页 > 后端技术 > PHP

PHP中DirectIO直接操作文件扩展的使用

时间:2023-03-29 21:31:46 PHP

关于PHP的文件操作,我们也会通过系列文章来学习。今天我们先来了解一个很少有人用过,甚至很多人都不知道的扩展。与我们日常的文件操作略有不同。然而,这些差异不是我们肉眼直观可见的。它们主要在于业务需求和性能之间的平衡。什么是DirectIODirectIO其实是Linux操作系统中的一个概念。意思是直接操作文件流,为什么说直接呢?其实我们的操作系统在进行文件操作的时候,并不是直接在磁盘上立即读写文件,中间有一层pagecache。既然是缓存,当然会带来一定的性能提升,但这也不是完全绝对的。直接操作就是忽略这一层的缓存操作,直接在磁盘上读写文件。我们都知道磁盘,即使是固态硬盘,与CPU和内存的处理速度之间存在着巨大的差距,而默认的pagecache就是用来弥补这个差距的。但是pagecache会增加cpu的计算操作,占用内存,而直接操作不会有这个问题,但是相对来说,它的速度比不上cachedfileread操作。以上就是对DirectIO的简单认识。更详细的解释可以参考文末参考文档中第二个链接的内容进行深入学习。在PHP中,我们直接从PECL下载DirectIO扩展,然后按照扩展的正常安装方法安装使用。由于创建和写入文件是文件操作,所以我们先创建和写入一些文件数据。$fd=dio_open("./test",O_RDWR|O_CREAT);echodio_write($fd,"ThisisTest.I'mZyBlog.Showmethemoney4i"),PHP_EOL;//43print_r(dio_stat($fd));//数组//(//[device]=>64768//[inode]=>652548//[mode]=>35432//[nlink]=>1//[uid]=>0//[gid]=>0//[device_type]=>0//[size]=>43//[block_size]=>4096//[blocks]=>8//[atime]=>1602643459//[mtime]=>1602656963//[ctime]=>1602656963//)dio_close($fd);与f系列函数类似,我们需要使用一个dio_open()函数来打开一个文件,而O_RDWR|O_CREAT参数表示打开一个Reads和write文件,如果不存在则创建。这两个常量对应Linux中直接操作文件相关的常量,也可以在文末链接中看到对这些常量的解释。写操作也可以用一个dio_write()来完成,返回的内容就是写入内容的长度。这里我们写了43个字符。dio_stat()是返回当前文件句柄的一些信息,我们可以看到设备号device、uid、gid、atime、mtime等信息,这些和我们在linux中看到的信息类似,其实一些这个文件的简单信息。读取文件读取文件可以使用一个函数非常简单地完成。$fd=dio_open("./test",O_RDWR|O_CREAT);echodio_read($fd),PHP_EOL;//这是测试。我是ZyBlog。给我看看money4idio_close($fd);dio_read()函数包含另一个参数,可以按照指定的字节长度读取内容。后面我们会看到相关的例子。文件操作在文件读取过程中,我们可能只需要读取一部分内容,或者从某个位置开始读取文件内容。下面的操作函数针对这两方面进行操作。$fd=dio_open("./test",O_RDWR|O_CREAT);var_dump(dio_truncate($fd,20));//bool(true)echodio_read($fd),PHP_EOL;//这是Test.I'mZyBdio_seek($fd,3);echodio_read($fd),PHP_EOL;//s是Test.I'mZyBdio_close($fd);其实从名字就可以看出dio_truncate()是用来截断文件内容的。这里我们从第20个字符开始截断,然后使用dio_read()只读取前20个字符。dio_seek()是指定从哪个字符读取内容。我们指定起始字符位置为3后,前三个字符将不会被读取。需要注意的是,dio_truncate()会修改原文件的内容,而dio_seek()则不会。其他设置$fd=dio_open('./test',O_RDWR|O_NOCTTY|O_NONBLOCK);dio_fcntl($fd,F_SETFL,O_SYNC);dio_tcsetattr($fd,array('baud'=>9600,'bits'=>8,'stop'=>1,'parity'=>0));while(($data=dio_read($fd,4))!=false){echo$data,PHP_EOL;}//This//is//Test//.I'm//ZyBdio_close($fd);}dio_fcntl()函数是调用的c函数库中的fcntl函数,目的是对文件描述符进行一些指定的操作,而这个操作也是用一些常量固定的,这里我们使用F_SETFL,意思是设置文件描述符标志为指定值,这个O_SYNC表示如果设置了这个描述符,文件的写操作会等到数据写入磁盘。当然这个函数还可以设置很多其他的操作符,可以参考PHP官方文档深入学习。dio_tcsetattr()用于设置打开文件的终端属性和波特率。Baud表示波特率,bits表示位,stop表示停止位,parity表示奇偶校验位。这方面的内容需要在《计算机组成原理》和《操作系统》中有一定的知识,我也不是很清楚,就不详细解释了。从这里可以看出,大学课堂上的基础课真的非常重要。相信学过这些专业基础课的同学,马上就能理解这个函数的作用。最后,我们使用dio_read()中的第二个参数,根据字节长度读取文件内容。可以看到读取的内容是以4个字符长度为单位输出的。学习汇总功能比较简单。核心的是要知道这个扩展更适合在哪些业务场景下使用。在文章开头的介绍中,我们已经说明了直接文件操作和普通文件操作的一些区别。在自缓存应用或者需要传输非常大的数据时,直接操作对CPU和内存比较友好。其他情况,我们还是使用系统默认的文件操作方式。事实上,在大多数情况下,我们很难看出它们之间的显着差异。所以在实际应用中,还是那句话,结合实际业务情况,选择最佳方案。测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202010/source/4。PHP中DirectIO直接操作文件扩展名的使用。PHP参考文档:https://www.php.net/manual/zh/book.dio.phphttps://www.ibm.com/developerworks/cn/linux/l-cn-directio/各媒体平台均可搜索【硬核项目经理】