Drupal中处理文件流File System和Stream Wrapper原理

在Drupal7以及PHP(也不知那个版本)后,多了一个概念:Stream,主要用来表示文件流。BTW,追溯起Stream的概念,这个应该很早在Java和C#等OOP的语言中已存在,PHP只是简单的封装了file/file_get_content等函数,使用起来方便,所以PHPer
们更少的在意stream以及整个底层的操作。

当我们使用一个完整的框架(如:drupal框架),drupal又更加完善了PHP中stream的概念和使用方式,使其更加OO,更加易用。

注意:PHP本身是支持StreamWrapper的,Drupal只是对其进行完善,因此PHP的函数,如move、
fopen、move_uploaded_file等函数是直接可以用scheme的形式访问(类似php://的形式),在PHP中增加一个
streamwrapper需要注册一个,需要调用stream_wrapper_register函数。

详情参考: http://php.net/..class.streamwrapper.php

Stream是什么?

Stream其实是一个抽象的概念,类似于传输层,位于文件系统的下层。跟Stream相连的就是存储,也就是Stream相当于一传输线,一端连接存储,一端连接程序。


File的操作

文件的操作基本就是读写,读写的位置其实就是stream,一般情况下读写本地文件,我们认为也是一个stream,可以认为
LocalFileStream,读写网络文件(FTP、HTTP、S3、阿里OSS、NFF等)也是一种stream,这样看来,文件的操作API其实应该是一个抽象的函数,而不是一个具体的函数。

用数据库作为类比,数据的open、prepare、update、execute、close就是有一个抽象的类,后端用什么数据库,就有对应的实现,参考下面的图片:


程序调用数据库的抽象接口,该接口根据数据库的url,按照不同的scheme返回不同的数据库操作类,完成对数据库的操作。

因此文件的操作,我们用数据库操作做对比,也可以用下图来表示:


通过上图,我们就可以理解,其实对文件的操作就是对流的操作,不同的流对应不同的存储介质,只是默认情况下,我们认为流就是本地文件,但是随着存储的日益复杂和云的兴起,对文件的操作已不能简单的理解为对本地文件的操作,而应该是对流(Stream)的操作。

因此,在其他语言里面stream是一个基类,根据不同的存储介质,stream有不同的实现,比如C#中的stream的集成关系如下,通过OO的方式,更好的理解stream的概念。


Drupal中File API和Stream Wrapper

一图顶万言,综合上面的理解,我们做了下面这张关系图,虽然不一定准确,但是可以帮助我们理解Drupal中file和stream
wrapper的关系。


Drupal的stream wrapper只是一个接口,可以实现任意的自定义stream wrapper。

Drupal的第三方stream wrapper:

Remote stream wrapper(http://、https://、feeds://)

https://www.drupal.org/project/remote_stream_wrapper

System stream wrapper (module://、theme://、profile://、library://)

https://www.drupal.org/project/system_stream_wrapper

因此,标准化的File操作,需要传进去一个带有scheme的path,在PHP中,默认的不带scheme就是本地文件。在Drupal中,默认的scheme是public,也是是本地文件的public目录。

StorageAPI 模块

Drupal中也许对上面的逻辑坐得不够完善,或许抽象层不是很完美,因此storageAPI模块出现了,它扩展的标准的Drupal文件操作,即使你对Drupal的file和stream不懂,装上这个模块,加上对应的service就能实现上图对云文件的操作。
如Amazon S3、Ftp、database等。

(笔者看来,StorageAPI就是对上面图中文件访问结构图中逻辑的实现和完善)

当然这个模块也有缺陷,那就是跟某些第三方模块的兼容的问题,并不是所有模块都能良好的兼容storage
api模块,这个也是drupal第三方模块的同病。

注意,要启用drupal文件对storageAPI的支持,需要启用Core Bridge 模块。

StorageAPI模块参考 https://drupal.org/project/storage_api

Storage api stream wrapper
:https://www.drupal.org/project/storage_api_stream_wrapper

后记

回顾第一段,PHP内部支持StreamWrapper,在Drupal中,对PHP的StreamWrapper进行了扩展,主要的Interface是:DrupalStreamWrapperInterface

Drupal本身通过这个Interface实现了DrupalLocalStreamWrapper,第三方模块实现了很多,如下:

HPCloud: HPCloudDrupalStreamWrapper

Storage API: StorageApiStreamWrapper

Storage Core Bridge: DrupalStorageStreamWrapper

时间: 2024-09-15 16:10:52

Drupal中处理文件流File System和Stream Wrapper原理的相关文章

Drupal中inc文件的用法实例

Drupal中inc文件是可以调用的php文件.Drupal中Inc文件作用是用来定义函数. Drupal中Inc文件的用法: 1.导入的方法module_load_include(); <?php// Load node.admin.inc from the node module.  module_load_include('inc', 'node', 'node.admin');  // Load content_types.inc from the node module.  modul

android从资源文件中读取文件流并显示的方法_Android

本文实例讲述了android从资源文件中读取文件流并显示的方法.分享给大家供大家参考.具体如下: 在android中,假如有的文本文件,比如TXT放在raw下,要直接读取出来,放到屏幕中显示,可以这样: private void doRaw(){ InputStream is = this.getResources().openRawResource(R.raw.ziliao); try{ doRead(is); }catch(IOException e){ e.printStackTrace(

详解C++编程中的文件流与字符串流_C 语言

C++文件流类与文件流对象 文件流是以外存文件为输入输出对象的数据流.输出文件流是从内存流向外存文件的数据,输入文件流是从外存文件流向内存的数据.每一个文件流都有一个内存缓冲区与之对应. 请区分文件流与文件的概念,不用误以为文件流是由若干个文件组成的流.文件流本身不是文件,而只是以文件为输入输出对象的流.若要对磁盘文件输入输出,就必须通过文件流来实现. 在C++的I/O类库中定义了几种文件类,专门用于对磁盘文件的输入输出操作. 除了标准输入输出流类istream.ostream和iostream

c#中创建文件流(System.IO.FileStream)出错

问题描述 我用c#写了个网站,当有用户登录时,便向一个日志文件中写入用户登录信息(包括登录时间,网站当前在线人数)等,前段时间这段代码还好好的,不知为什么,上次重做了机器后,这段代码便运行不过去了!肯请专家指教!!代码如下:privatestaticvoidWriteLog(stringsessionid,stringuserid,intflag){try{if(isLog){System.IO.FileStreamfs=newSystem.IO.FileStream(@"c:clientuse

c# .net中下载文件及图片文件的防盗链功能实现方法

在c#.net中可以利用app_data文件夹来实现下载文件及图片文件的防盗链功能. 原理一:在asp教程.net中app_data文件夹包含应用程序的本地数据存储.它通常以文件(诸如microsoft access或microsoft sql server express数据库教程.xml文件.文本文件以及应用程序支持的任何其他文件)形式包含数据存储.该文件夹内容不由asp.net教程处理,也就是说浏览者无法直接访问此文件夹,因此我们可以利用这一权限特性来实现防盗链. 原理二:对来访请求地址进

ortable evice-C++ 问题 在用MTP协议 就是IPortableDevice获取文件流问题

问题描述 C++ 问题 在用MTP协议 就是IPortableDevice获取文件流问题 如何获取MTP设备的中某个文件流的某一部分,比如获取一个文件流的中间1000个字节

file和file文件流

**io流是程序中比较常用的功能,基本上涉及到文件上传下载的都要用到这功能,比如上传头像,上传附件等等. 对于一个java程序员来说,io流也是必须掌握的,因此这里对比较常用的或者说曾经用过的方法进行简单的归纳和总结.** 对于io流,百度百科的解释是: 流是一种抽象概念,它代表了数据的无结构化传递.按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列.从流中取得数据的操作称为提取操作,而向流中添加数据的操作称为插入操作.用来进行输入输出操作的流就称为IO流.换句话说,IO流就是以流的方

C++中文件流的读写,在文件中录入相关对象数组信息,然后显示出来

问题描述 C++中文件流的读写,在文件中录入相关对象数组信息,然后显示出来 我想实现一个书籍的录入.修改.删除购买等一系列功能 定义了一个Book类 想实现将键盘上的信息录入到对象数组中,然后将对象数组中的信息写入到文本文件中, 所以定义了一个文件对象数组指针,用循环将Book中的对象与文件中对象相匹配 从而能够录入到文本文件中,修改时文本文件也同时修改,删除时文本文件中相应的信息也被删除 最后将实现这些功能后最新的book信息显示出来 --------我表达能力一直不怎么好,不知道大家听懂了没

android开发-安卓开发中read-only file system

问题描述 安卓开发中read-only file system android模拟机上不能加文件提示read only file system 是什么问题啊 mount -o remount ,rw /都试过了 ,没什么用额. 使用重新挂载还是无用 mount -o remount,rw rootfs /system/ mount -o remount,rw rootfs /system/ cd sdcard cd sdcard mkdir a mkdir a mkdir failed for