本文共 2758 字,大约阅读时间需要 9 分钟。
流是二进制数据串在端与端之间的传输。在 Cocoa 中提供了 NSStream 、NSInputStream 、NSOutputStream 三个类来实现数据通过流的方式在文件、内存、网络之间的传输。
NSStream 是一个抽象类,它是 NSInputStream 和 NSOutputStream 类的父类。NSInputStream 是输入流,流中的数据可能来自本地文件,也可能来自网络资源,应用从输入流中读取到数据后,便可以进行必要的处理了。NSOutputStream 是输出流,将处理后的数据写入输出流中,而后数据传输到目标,这个目标可以是本地文件,也可以是网络上的某个地址。但是,这种较为底层的数据处理方式,如无必要,可以使用 NSURL 或 NSFileHandle 代替。
NSStream 类作为流的抽象类,定义了一些基本的方法和属性。在自定义 NSSteam 子类时,应重写其中的方法。
- (void)open;- (void)close;- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode;- (void)removeFromRunLoop:(NSRunLoop *)aRunLoop forMode:(NSRunLoopMode)mode;
当流创建并开启后,会占用一些系统资源,所以流使用结束后,应主动关闭,关闭后的流不能再次开启,但是其相关属性仍可以访问。如果流被添加到运行循环中,关闭时应将其移出运行循环。
#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)- (nullable id)propertyForKey:(NSStreamPropertyKey)key;- (BOOL)setProperty:(nullable id)property forKey:(NSStreamPropertyKey)key;#else- (nullable id)propertyForKey:(NSString *)key;- (BOOL)setProperty:(nullable id)property forKey:(NSString *)key;#endif
通过上面的方法,可以获取流相关的属性配置,可选的属性如下:
//流的状态@property (readonly) NSStreamStatus streamStatus;typedef NS_ENUM(NSUInteger, NSStreamStatus) { NSStreamStatusNotOpen = 0, NSStreamStatusOpening = 1, NSStreamStatusOpen = 2, NSStreamStatusReading = 3, NSStreamStatusWriting = 4, NSStreamStatusAtEnd = 5, NSStreamStatusClosed = 6, NSStreamStatusError = 7};
流的代理可以不指定,如果不指定,那么流本身即为代理对象,应实现代理方法。
//流的代理@property (nullable, assign) iddelegate;//NSStreamDelegate 协议中的唯一的方法- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
这个代理方法可以用来处理流的相关事件,可能的事件如下:
NSStream 流并不支持套接字连接,要实现远程客户端套接字交互,可以使用 CFStream 的相关接口。
创建 NSInputStream 实例对象时,应当指定数据源,数据源可以是文件、内存或网络资源。
NSInputStream 中的属性 hasBytesAvailable 值表示了当前输入流中是否有可以读取的数据,如果该属性值为 YES 那么可以调用流的方法进行读取。
//buffer 是提供的缓存地址//len 是可以读取的数据的最大字节数//返回实际读取的数据字节数- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len;
创建 NSOutputStream 实例对象时,应当指定数据输出的目标,该目标可以是内存、本地文件或网络地址。
NSOutputStream 的属性 hasSpaceAvailable 值如果为 YES ,则表示可以向流中写入数据。
//buffer 从指定的缓存中向流中写入数据//len 可以写入的数据最大字节数//返回实际向流中写入的数据字节数- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)len;
如果输出流的目标为内存,那么可以使用 NSStreamDataWrittenToMemoryStreamKey 获取最终输出的数据。
NSStreamDelegate 该协议只有一个方法,该方法用来处理与流相关的事件。
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
转载地址:http://txdws.baihongyu.com/