PHP中DirectIO操作文件扩展的用法大全

关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习。今天我们先学习的是一个很少人使用过,甚至很多人根本不知道的扩展,它与我们日常的文件操作有些许的不同。不过这些差别并不是我们肉眼所能直观看到的,主要还是在于业务的需求与性能的平衡。

什么是Direct IO

Direct IO 其实是 Linux 操作系统中的一个概念。它的意思是直接操作文件流,为什么说是直接呢?其实在我们的操作系统进行文件操作的时候,并不是马上直接就在磁盘上进行文件的读写,中间还有一层页缓存。既然是缓存,那么它当然是会带来一定的性能提升,但这也并不是完全绝对的。而直接操作就是忽略掉这一层的缓存操作,直接对磁盘上的文件进行读写。我们都知道,磁盘,即使是固态硬盘,它和 CPU 以及内存的处理速度之间都是有着巨大的落差的,默认的页缓存就是用来弥补这种差距。但是页缓存会加大 CPU 的运算操作以及占用内存,而直接操作则不会有这种问题,但是相对来说,它的速度并不能和带缓存的文件读取操作相媲美。

以上是关于 Direct IO 的一个简单的理解,更详尽的解释大家可以参考文末参考文档中第二条链接的内容并进行深入的学习。在 PHP 中,我们直接在 PECL 下载 Direct IO 扩展就可以按照扩展的正常安装方式进行安装使用。

创建写入文件

既然是文件操作,那么我们首先还是来创建和写入一些文件数据。

$fd = dio_open("./test", O_RDWR | O_CREAT);

echo dio_write($fd, "This is Test.I'm ZyBlog.Show me the money4i"), PHP_EOL;
// 43

print_r(dio_stat($fd));
// Array
// (
//     [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 参数的意思是打开一个可读写文件,并且如果文件不存在的话,创建它。这两个常量是与 Linux 中相关的直接操作文件的常量对应的,在文末的链接中也可以看到关于这些常量的解释。

写入操作也是同样的使用一个 dio_write() 就能够完成,它返回的内容是写入的内容长度,这里我们写入了 43 个字符。

dio_stat() 是返回当前文件句柄的一些信息,我们可以看到设备号 device 、uid 、 gid 、 atime 、 mtime 等一些信息,它们和我们在 Linux 中能够看到的信息类似,其实就是这个文件的一些简单的信息。

读取文件

读取文件使用非常简单的使用一个函数就可以完成。

$fd = dio_open("./test", O_RDWR | O_CREAT);

echo dio_read($fd), PHP_EOL;
// This is Test.I'm ZyBlog.Show me the money4i

dio_close($fd);

dio_read() 函数还包含另外一个参数,可以按指定的字节长度读取内容,这个在后面我们还会看到相关的示例。

文件操作

在文件的读取过程中,我们有可能只需要读取一部分的内容,或者从某一位置开始读取文件内容,下面的操作函数就是针对这两个方面进行操作的。

$fd = dio_open("./test", O_RDWR | O_CREAT);

var_dump(dio_truncate ($fd , 20));
// bool(true)
echo dio_read($fd), PHP_EOL;
// This is Test.I'm ZyB

dio_seek($fd, 3); 

echo dio_read($fd), PHP_EOL;
// s is Test.I'm ZyB

dio_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
//  ZyB

dio_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.php

https://www.ibm.com/developerworks/cn/linux/l-cn-directio/

到此这篇关于PHP中DirectIO直操作文件扩展的使用的文章就介绍到这了,更多相关php扩展的使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • PHP获取文件扩展名的4种方法

    本文实例讲述了PHP获取文件扩展名的4种方法.分享给大家供大家参考,具体如下: $filename="123.jpg"; //方法一: function get_ext($file_name){ return array_pop(explode('.', $file_name)); //用.号对字符串进行分组 } echo get_ext($filename); //方法二: $fileEx=strtolower(substr(strrchr($filename,".&quo

  • PHP中获取文件扩展名的N种方法小结

    第1种方法: 复制代码 代码如下: function get_extension($file) { substr(strrchr($file, '.'), 1); } 第2种方法: 复制代码 代码如下: function get_extension($file) { return substr($file, strrpos($file, '.')+1); } 第3种方法: 复制代码 代码如下: function get_extension($file) { return end(explode(

  • php文件扩展名判断及获取文件扩展名的N种方法

    下面代码是php文件扩展名判断 <!DOCTYPE> <html> <head> <meta http-equiv="Content-type" content="text/html" charset="utf-8"> <title>check file</title> </head> <body> <b>文件扩展名验证</b>

  • PHP获取文件扩展名的常用方法小结【五种方式】

    本文实例总结了PHP获取文件扩展名的常用方法.分享给大家供大家参考,具体如下: 这是我应聘实习时遇到的一道笔试题: 使用五种以上方式获取一个文件的扩展名. 要求:dir/upload.image.jpg,找出 .jpg 或者 jpg , 必须使用PHP自带的处理函数进行处理,方法不能明显重复,可以封装成函数,比如 get_ext1($file_name), get_ext2($file_name) 下面是我参考网上资料总结出来的五种方法,都比较简单,话不多说,直接上代码: 方法1: functi

  • php获取文件名称和扩展名的方法

    php获取文件名称和扩展名 1.basename()-返回路径的文件名 请看下面php代码: <?php $path = "/usr/www/html/index.php"; echo basename($path)."<br>"; //如果选择suffix则忽略扩展名 echo basename($path,".php"); ?> 运行结果: index.php index 2.dirname()-返回当前脚本的文件路径

  • PHP中DirectIO操作文件扩展的用法大全

    关于 PHP 的文件操作,我们也将是通过一系列的文章来进行学习.今天我们先学习的是一个很少人使用过,甚至很多人根本不知道的扩展,它与我们日常的文件操作有些许的不同.不过这些差别并不是我们肉眼所能直观看到的,主要还是在于业务的需求与性能的平衡. 什么是Direct IO Direct IO 其实是 Linux 操作系统中的一个概念.它的意思是直接操作文件流,为什么说是直接呢?其实在我们的操作系统进行文件操作的时候,并不是马上直接就在磁盘上进行文件的读写,中间还有一层页缓存.既然是缓存,那么它当然是

  • python中os操作文件及文件路径实例汇总

    本文实例讲述了python中os操作文件及文件路径的方法.分享给大家供大家参考.具体分析如下: python获取文件上一级目录:取文件所在目录的上一级目录 复制代码 代码如下: os.path.abspath(os.path.join(os.path.dirname('settings.py'),os.path.pardir)) os.path.pardir是父目录,os.path.abspath是绝对路径 举例具体看一下输出: 复制代码 代码如下: print os.path.dirname(

  • CI框架中数据库操作函数$this->db->where()相关用法总结

    本文实例总结了CI框架中数据库操作函数$this->db->where()相关用法.分享给大家供大家参考,具体如下: CI 框架数据库操作函数 this->db->where() 的使用 1) $this->db->where('MATCH (field) AGAINST ("value")', NULL, FALSE) 如果把$this->db->where() 接受可选的第三个参数设置为 FALSE, CodeIgniter 将不会为

  • C++中SetConsoleCursorPosition()移动光标函数的用法大全

    SetConsoleCursorPosition()来自于文件"windows.h",使用时记得引用此头文件. 首先说一下,这个函数的功能即是字面意思,即移动命令行中光标的位置.这里要注意的是,每次调用这个函数都是默认从左上角开始偏移,而与当前光标停留的位置无关. 然后我们剖析下这个函数,我们查看定义发现,调用这个函数需要传入两个参数,都是自定义类型,分别为 HANDLE 和 COORD. SetConsoleCursorPosition( _In_ HANDLE hConsoleOu

  • linux中scp命令和scp命令用法大全

    scp就是secure copy,是用来进行远程文件拷贝的.数据传输使用ssh1,并且和ssh1使用相同的认证方式,提供相同的安全保证.与rcp不同的是,scp会要求你输入密码如果需要的话. svn 删除所有的 .svn文件 find . -name .svn -type d -exec rm -fr {} \; linux之cp/scp命令+scp命令详解 名称:cp 使用权限:所有使用者 使用方式: cp [options] source dest cp [options] source..

  • 在PHP中操作文件的扩展属性

    在操作系统的文件中,还存在着一种我们可以自己定义的文件属性.这些属性不是保存在文件内容中,也不是直接可以通过 ls -al 所能看到的内容.它们可以将一个键值对信息永久得关联到文件上,一般现在的 Linux 系统都支持这样的文件扩展属性的功能.在操作系统中我们可以通过 setfattr. getfattr. attr 这些命令来操作它们.当然,PHP 也为我们提供了一个扩展可以用于对文件的扩展属性进行操作. 添加扩展属性 $file = __FILE__; var_dump(xattr_set(

  • Node.js程序中的本地文件操作用法小结

    Node最引以为傲的就是它有一个非常小的核心.有一些语言绑定了完整的POSIX API,而 Node实现了尽可能少的绑定,并通过同步.异步或流API形式暴露他们. 这种方法意味着,操作系统中有一些非常方便的功能,需要在Node中重建.这是一个教你如何使用文件系统软件包的实用教程. 引用文件 与文件系统的交互很重要的一点是要指向正确的文件.由于NPM的包使用相对路径引用,所以你不能把路径写死在代码.有两个主要方式来以确保包能引用到正确的文件: // 使用 `path.join()` 而不是 `+`

  • Laravel4中的Validator验证扩展用法详解

    本文实例讲述了Laravel4中的Validator验证扩展用法.分享给大家供大家参考,具体如下: 不管写接口还是写web页面,实质都是传入参数,然后进行业务逻辑,然后再输出具体内容.所以,对参数的验证是不可避免的一个环节,比如传过来的email是不是为空,是不是合法的email格式?laravel已经为phper想到简化这种逻辑的办法了.就是Validator. Validator的使用 制造一个验证器 validator使用Validator::make可以制造一个验证器.然后使用验证器判断

  • Laravel中基于Artisan View扩展包创建及删除应用视图文件的方法

    本文实例讲述了Laravel中基于Artisan View扩展包创建及删除应用视图文件的方法.分享给大家供大家参考,具体如下: 1.简介 本扩展包添加了两个视图相关的Artisan命令到Laravel应用,以便我们通过Artisan命令即可创建和管理视图文件,可谓是进一步解放了生产力. 2.安装 还是通过Composer安装: composer require sven/artisan-view 安装完成后到config/app.php中注册服务提供者ArtisanViewServiceProv

随机推荐