流提供了一种简单的方式在不同和介质中交换数据,这种交换方式是与设备无关的。流是在通信路径中串行传输的连续的比特位序列。从编码的角度来看,流是单向的,因此流可以是输入流或输出流。除了基于文件的流外,其它形式的流都是不可查找的,这些流的数据一旦消耗完后,就无法从流对象中再次获取。
在Cocoa中包含三个与流相关的类:NSStream、NSInputStream和NSOutputStream。NSStream是一个抽象基类,定义了所有流对象的基础接口和属性。NSInputStream和NSOutputStream继承自NSStream,实现了输入流和输出流的默认行为。下图描述了流的应用场景:
从图中看,NSInputStream可以从文件、socket和NSData对象中获取数据;NSOutputStream可以将数据写入文件、socket、内存缓存和NSData对象中。这三处类主要处理一些比较底层的任务。
流对象有一些相关的属性。大部分属性是用于处理网络安全和配置的,这些属性统称为SSL和SOCKS代理信息。两个比较重要的属性是:
NSStreamDataWrittenToMemoryStreamKey:允许输出流查询写入到内存的数据
NSStreamFileCurrentOffsetKey:允许操作基于文件的流的读写位置
可以给流对象指定一个代理对象。如果没有指定,则流对象作为自己的代理。流对象调用唯一的代理方法stream:handleEvent:来处理流相关的事件:
对于输入流来说,是有可用的数据可读取事件。我们可以使用read:maxLength:方法从流中获取数据
对于输出流来说,是准备好写入的数据事件。我们可以使用write:maxLength:方法将数据写入流
Cocoa中的流对象与Core Foundation中的流对象是对应的。我们可以通过toll-free桥接方法来进行相互转换。NSStream、NSInputStream和NSOutputStream分别对应CFStream、CFReadStream和CFWriteStream。但这两者间不是完全一样的。Core Foundation一般使用回调函数来处理数据。另外我们可以子类化NSStream、NSInputStream和NSOutputStream,来自定义一些属性和行为,而Core Foundation中的流对象则无法进行扩展。
上面主要介绍了iOS中流的一些基本概念,我们下面将介绍流的具体使用,首先看看如何从流中读取数据。
Stream Programming Guide