我有一个以NSInputStream作为参数的消费者类,这个参数将被异步处理,我想推送来自生产者类的数据,该生产者类需要提供一个NSOutputStream作为其输出源。现在,我如何设置一个缓冲(或透明)流来充当生产者的输出流,同时又充当我的消费者类的NSInputStream?
我看过一点NSOutputStream +outputStreamToMemory和+outputStreamToBuffer:capacity:,但还没有真正弄清楚如何将它用作NSInputSource的输入。
我有一些想法,建立一个持有实际缓冲区的中间人类,然后创建两个子类(每个NSInput/OutputStream一个)来持有对这个缓冲类的引用,并让这些子类将大多数调用委托给那个类,例如输出子类方法hasSpaceAvailable,write:maxLength:,而对于输入,hasBytesAvailable,read:maxLength:等。
任何关于如何处理这种情况的提示都是值得感谢的。谢谢。
发布于 2011-12-06 22:43:44
要做到这一点,一种方法是使用苹果开发人员网站上的示例代码。SimpleURLConnection example
这是如何做的,可以在PostController.m代码中看到
@interface NSStream (BoundPairAdditions)
+ (void)createBoundInputStream:(NSInputStream **)inputStreamPtr outputStream:(NSOutputStream **)outputStreamPtr bufferSize:(NSUInteger)bufferSize;
@end
@implementation NSStream (BoundPairAdditions)
+ (void)createBoundInputStream:(NSInputStream **)inputStreamPtr outputStream:(NSOutputStream **)outputStreamPtr bufferSize:(NSUInteger)bufferSize
{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
readStream = NULL;
writeStream = NULL;
CFStreamCreateBoundPair(
NULL,
((inputStreamPtr != nil) ? &readStream : NULL),
((outputStreamPtr != nil) ? &writeStream : NULL),
(CFIndex) bufferSize);
if (inputStreamPtr != NULL) {
*inputStreamPtr = [NSMakeCollectable(readStream) autorelease];
}
if (outputStreamPtr != NULL) {
*outputStreamPtr = [NSMakeCollectable(writeStream) autorelease];
}
}
@end基本上,您可以使用缓冲区将两个流的末端连接在一起。
发布于 2012-03-19 18:41:24
您可能想要考虑将NSInputStream子类化,并将源流包装在新类中,以便在字节通过时对其进行缓冲和/或修改。
我发现使用绑定套接字方法的主要原因是为了支持寻道。基于文件的NSInputStreams使用流属性在文件中查找,如果没有子类化,我就不能轻松地安排这一点。
这种方法的一个问题是,免费桥接似乎不适用于你的子类--但有一篇非常好的文章,如果你需要一个模板子类,它也会给你一个开始:
http://bjhomer.blogspot.co.uk/2011/04/subclassing-nsinputstream.html
我得到了一个使用这两种方法的缓冲解决方案-尽管我使用子类方法的另一个问题是您需要注意将事件适当地发送到侦听器-例如,当源流向您发送EOF事件时,您不会将其传递给您的使用者,直到他们清空了缓冲区-所以这里有一些混乱的事情要做。
此外,您可能需要确保客户端在主运行循环之外进行读取(我让它与全局中央调度一起工作),因为您在子类中所做的任何观察-在源码流上-都会与使用者发生冲突。虽然您似乎能够选择任何运行循环来观察其上的流,但只有一个主循环有效。
因此,总的来说,我会说使用配对的流,除非你需要支持搜索-或者特别反对配对的流方法。
发布于 2015-02-04 18:01:47
下面是一个已经实现的类,它可以做您想要做的事情
BufferOutputStreamToInputStream
// initialize
self.bufferWriter = [[BufferOutputStreamToInputStream alloc] init];
[self.bufferWriter openOutputStream];
// later you want to set the delegate of the inputStream and shedule it in runloop
// remember, you are responsible for the inputStream, the outputStream is taken care off;)
self.bufferWriter.inputStream.delegate = self;
[self.bufferWriter.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.bufferWriter.inputStream open]
// fill with data when desired on some event
[self.bufferWriter addDataToBuffer:someData];https://stackoverflow.com/questions/3221030
复制相似问题