`

第四章 管道和缓冲器

阅读更多

第四章 管道和缓冲器

本文译自 《TangoRefMan_Sep_1_2008.odt 》

 

管道和缓冲器是tango IO 的基础。

 

 管道(conduits)

 

Tango IO 是面向流的:每个数据最终被描述为一个Tango概念叫管道(conduits),包括InputStream和OutputStream。 例如,有一些管道用于文件、套接字(sockets)和控制台等的交互操作。一些管道要求明确的连接到终点,而另一些连接不明确(socket conduits是明确连接的一个变体)。文件和控制台管道通常是不明确地连接。有一些扩展让不同步读、写操作成为可能,通过各种具体操作系统方便的支持(见tanog.io.selector)。

 

管道是双向的,支持邻近的读和写,通过关联一个输入流(InputStream)进行读操作,通过关联一个输出流(OutputStream)进行写操作,访问分别通过管道的input()方法和output()方法。通常应用程序的交互作用是用管道流的read/write方法。每个方法接受一个无类型数组然后返回一个整数数组,描述构成量(quantitypopulated)和消耗量(consumed)。

 

注意在有些情况下,返回值少于数组长度(array-length)提供的值。实际上,保留常量IConduit.Eof返回流程末尾(end-of-flow)状态:

 

InputStream input();

OutputStream output();

 

InputStream

 

void clear();

Iconduit conduit();

uint read (void[] dst);

 

OutputStream

 

void  flush();

Iconduit   conduit();

uint  write(void[] src);

OutputStream  copy(InputStream src);

 

输出流方法(OutputStream)提供完整刷新一个数组并复制另一个管道的内容。这两种方法,可以同时完成,取决于管道末端(end-point)。

 

管道支持流过滤器的概念:一个或多个过滤器被绑到管道上,流过过滤器的数据会被拦截和改变。文件过滤器通过这些管道方法用颠倒顺序连接。返回上一个绑定的过滤器:

 

InputStream  attach(InpuStream filteer);

OutputStream  attach(OutpuStream filter);

 

管道过滤器像预期的一样链接在一起,如,一个过滤器read()方法调用它的祖先的read()方法。然而,如果看起来适合,过滤器会更改流向。过滤器基类在tango.io.Conduit模块中。

 

值得注意的是这些过滤器被有效地包容在管道自身之中,而不是把过滤器暴露出来作为IO活动的大门,这就允许管道细节(如socket属性、文件搜寻)隐藏在更少的界面之后。

 

再次提醒,管道不再需要使用时,应该被应用程序明确地关闭,以便于执行管道的清除行为并释放任何捆绑的过滤器。

 

管道异常

 

作为一个规则,管道不要乱扔异常,因为有些错误情况经常被认为是有效的。例如,IConduit.Eof一般完好无损地传回给应用程序。不过,如果底层操作系统检测到一些故障类型,异常还是会抛出。

 

 

缓冲器(Buffers)

 

缓冲一个管道应用到那里的内容相当于滑动窗口(sliding window),并且简化大多数通用操作如记号解析(token-parsing)和输出一系列相关事件,缓冲器也能提高可靠的IO应用程序的处理能力。例如 :缓冲使下面的管道读写大块的数据而不是分散的小块数据元素,它提供一个临时的空间给可靠的算法高效率地改变流内容;并且支持高效率地数据记录内容映射到用户内存。缓冲器是全双工的,它保持不同的读写存储位置——因此,当写到一个缓冲器的末尾附近时,可同时读另一个的开始部分。

 

缓冲器提供了必要的功能来处理许多类型的缓冲活动,从简单的附加操作到更平凡的生产/消费之间的管道带宽的平衡。同时也支持多个客户端。如,多于一个的reader和/或writer可能被捆绑到一个缓冲器,并且缓冲器将维护一个穿越它们(缓冲器)的常见的状态,这是非常方便的。例如 ,一个应用程序必须涉及一个混合或交叉存取(mixed or interleaved)协议(protocol)-----这样的客户端会连续操作,与并发形成对照。当使用一个没有协定的客户端时,缓冲器自身的数据类型是不可知的。这是一个聪明的数组,冲洗和/或通过管道回填本身是必要的。

 

一个缓冲器通常捆绑到一个管道,它能轻松的单独使用。如基于内存的累加器。在这些情况下,缓冲器客户端用完全相同的方式被添加,用相同的方式操作,有一个区别:一个没有绑定管道的缓冲器在填满容积时不能自动的被清仓,因此,这种情况发生时将抛出一个异常。不断增长的缓存可以用来处理这个情景。

 

一个缓冲器的通常用法包含下列方法:

 

Ibuffer append (void[] src);

uint read(void[] dst);

void[] slice();

Ibuffer fill();

Ibuffer flush();

Ibuffer clear();

Iconduit conduit();

 

这些方法通常是不常见:

 

bool truncate(uint extent);

bool truncate(uint extent);

bool next(uint delegate(void[] tokenizer);

Void[] getContent();

Ibuffer setContent(void[] content);

Ibuffer copy(Iconduit src);

Iconduit compress();

 

另一个缓冲器变体包装操作系统设施陈列内存映射文件(memory-mapped files)。缓冲内存(通常)被直接映射到一个大文件中,那个文件可以被看作刚才的那个缓冲器,或更确切地作为一个无类型数组(void [])。

 

缓冲器异常

 

当没有连接到一个管道,一个缓冲区溢出状态可能会发生,导致一个异常被抛出。在适当的地方,用一个扩大的缓冲器正确管理溢出条件。

分享到:
评论
1 楼 oldrev 2009-02-09  
good job and do not give up

相关推荐

    lua 程序设计学习.doc 版

    第4章 基本语法 4.1 赋值语句 4.2 局部变量与代码块(block) 4.3 控制结构语句 4.4 break和return语句 第5章 函数 5.1 多返回值 5.2 可变参数 5.3 命名参数 第6章 再论函数 6.1 闭包 6.2 非全局函数 6.3 正确的尾...

    精通LINUX下的C编程(配套光盘)第一部分

    第4章 标准I/O库 4.1 概述 4.2 流和FILE对象 4.3 打开和关闭流 4.4 读和写流 4.5 流文件定位 4.6 文件结束和错误 4.7 流缓冲 4.8 格式化I/O 4.9 临时文件 4.10 小结 习题 第5章 进程操作 5.1 进程...

    精通LINUX下的C编程(配套光盘)第二部分

    第4章 标准I/O库 4.1 概述 4.2 流和FILE对象 4.3 打开和关闭流 4.4 读和写流 4.5 流文件定位 4.6 文件结束和错误 4.7 流缓冲 4.8 格式化I/O 4.9 临时文件 4.10 小结 习题 第5章 进程操作 5.1 进程...

    精通LINUX下的C编程(配套光盘)第三部分

    第4章 标准I/O库 4.1 概述 4.2 流和FILE对象 4.3 打开和关闭流 4.4 读和写流 4.5 流文件定位 4.6 文件结束和错误 4.7 流缓冲 4.8 格式化I/O 4.9 临时文件 4.10 小结 习题 第5章 进程操作 5.1 进程...

    Linux编程从入门到精通

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 ...

    Linux编程白皮书

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 ...

    LINUX编程白皮书 (全集)

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 ...

    Linux编程资料

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 ...

    Java开发详解.zip

    010401_【第4章:数组与方法】_数组的定义及使用笔记.pdf 010402_【第4章:数组与方法】_方法的声明及使用笔记.pdf 010403_【第4章:数组与方法】_数组的引用传递笔记.pdf 010404_【第4章:数组与方法】_Java新特性...

    UNIX环境高级编程_第二版中文

    第4章 文件和目录  4.1 引言  4.2 stat、fstat和lstat函数  4.3 文件类型  4.4 设置用户ID和设置组ID  4.5 文件访问权限  4.6 新文件和目录的所有权  4.7 access函数  4.8 umask函数  4.9 chmod...

    LINUX编程白皮书

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 ...

    linux编程白皮书

    1.1.4 控制器和外设 8 1.1.5 地址空间 9 1.1.6 时钟 9 1.2 软件基础 9 1.2.1 计算机语言 9 1.2.2 什么是操作系统 11 1.2.3 内核数据结构 13 第2章 内存管理 15 2.1 虚拟内存抽象模型 15 2.1.1 请求调页 17 2.1.2 ...

    寒江独钓-Windows内核安全编程(高清完整版).part4

    第4章 键盘的过滤 56 4.1 技术原理 57 4.1.1 预备知识 57 4.1.2 Windows中从击键到内核 58 4.1.3 键盘硬件原理 60 4.2 键盘过滤的框架 61 4.2.1 找到所有的键盘设备 61 4.2.2 应用设备扩展 64 4.2.3 键盘过滤模块的...

    UNIX环境高级编程(第二版中文)

    第4章 文件和目录 71 4.1 引言 71 4.2 stat、fstat和lstat函数 71 4.3 文件类型 72 4.4 设置用户ID和设置组ID 74 4.5 文件访问权限 75 4.6 新文件和目录的所有权 77 4.7 access函数 77 4.8 umask...

    UNIX环境高级编程

    第4章 文件和目录 71 4.1 引言 71 4.2 stat、fstat和lstat函数 71 4.3 文件类型 72 4.4 设置用户ID和设置组ID 74 4.5 文件访问权限 75 4.6 新文件和目录的所有权 77 4.7 access函数 77 4.8 umask...

    UNIX 高级教程系统技术内幕

    第4 章 信号和会话管理(72) 4.1 简介 4.2 信号生成和处理 4.2.1 信号处理 4.2.2 信号生成 4.2.3 典型情景 4.2.4 睡眠和信号 4·3 不可靠信号 4.4 可靠的信号 4.4.1 主要特性 4.4.2 SVR3 的实现 4.4.3 BSD 信号管理 ...

Global site tag (gtag.js) - Google Analytics