對于 NSInputStream 和 NSOutputStream 一直沒怎么搞清楚硫豆,今天抽一些時間在此記錄一下!
NSInputStream 與 NSOutputStream 都繼承于 NSStream, NSStream 是一個抽象的基類, 規(guī)定了Stream共有的一些行為…
什么是Stream
Stream翻譯成為流浩村,它是對我們讀寫文件的一個抽象雁比。 你可以這樣想象,當你讀文件和寫文件的時候翔怎,文件的內容就像水流一樣嘩嘩的 像你流過來或者流給別人彬碱,這樣豈不是很爽豆胸。 而Stream就幫我們做了這樣的事情, 實際上堡妒,它是把文件的內容配乱,一小段一小段的讀出或 寫入溉卓,來到達這樣的效果
NSStream
NSStream 是Cocoa平臺下對流這個概念的實現(xiàn)類皮迟, NSInputStream 和 NSOutputStream 則是它的兩個子類,分別對應了讀文件和 寫文件桑寨。
NSInputStream
NSInputStream 對應的是讀文件伏尼,所以要記住它是要將文件的內容讀到內存(你聲明的一段buffer)里, 下面一段是測試代碼
- (void)doTestInputStream {
NSString *path = @"/Users/usr/Desktop/stream.txt";
NSInputStream *readStream = [[NSInputStream alloc]initWithFileAtPath:path];
[readStream setDelegate:self];
[readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[readStream open]; //調用open開始讀文件
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventHasBytesAvailable:{
uint8_t buf[1024];
NSInputStream *reads = (NSInputStream *)aStream;
NSInteger blength = [reads read:buf maxLength:sizeof(buf)]; //把流的數(shù)據放入buffer
NSData *data = [NSData dataWithBytes:(void *)buf length:blength];
NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
}
break;
//錯誤和無事件處理
case NSStreamEventErrorOccurred:{
}
break;
case NSStreamEventNone:
break;
//打開完成
case NSStreamEventOpenCompleted: {
NSLog(@"NSStreamEventOpenCompleted");
}
break;
default:
break;
}
}
@end
NSOutputStream
NSOutputStream 對應的是寫文件,它是要將已存在的內存(buffer)里的數(shù)據寫入文件, 下面同樣一段是測試代碼
- (NSData *)dataWillWrite {
static? NSData *data = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
data = [NSData dataWithContentsOfFile:@"/Users/usr/Desktop/stream.txt"];
});
return data;
}
- (void)doTestOutputStream {
NSString *path = @"/Users/usr/Desktop/stream-write.txt";
NSOutputStream *writeStream = [[NSOutputStream alloc] initToFileAtPath:path append:YES];
[writeStream setDelegate:self];
[writeStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[writeStream open];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
switch (eventCode) {
case NSStreamEventHasSpaceAvailable: {
NSInteger bufSize = 5;
uint8_t buf[bufSize];
if (self.location + bufSize > [self dataWillWrite].length) {
[[self dataWillWrite] getBytes:buf
range:NSMakeRange(self.location, self.location + bufSize - [self dataWillWrite].length)];
}
else {
[[self dataWillWrite] getBytes:buf range:NSMakeRange(self.location, bufSize)];
}
NSOutputStream *writeStream = (NSOutputStream *)aStream;
[writeStream write:buf maxLength:sizeof(buf)]; //把buffer里的數(shù)據尉尾,寫入文件
self.location += bufSize;
if (self.location >= [[self dataWillWrite] length] ) { //寫完后關閉流
[aStream close];
}
}
break;
case NSStreamEventEndEncountered: {
[aStream close];
}
break;
//錯誤和無事件處理
case NSStreamEventErrorOccurred:{
}
break;
case NSStreamEventNone:
break;
//打開完成
case NSStreamEventOpenCompleted: {
NSLog(@"NSStreamEventOpenCompleted");
}
break;
default:
break;
}
}
用途
NSInputStream 和 NSOutputStream 常用與網絡傳輸中爆阶,比如要將一個很大的文件傳送給服務器,那么NSInputStream這時候是 很好的選擇, 我們可以查看到 NSURLRequest 有一個屬性叫HTTPBodyStream沙咏, 這時只要設置好一個NSInputStream的實例就可以 了辨图,最大的好處就是可以節(jié)省我們很多的內存≈辏或者是從服務器下載一個大文件數(shù)據,往往會造成內存暴漲,此時用NSOutputStream對文件進行操作就能解決此問題.(也可以用NSFileHandle)
另外要說明的是故河,NSInputStream 和 NSOutputStream其實是對 CoreFoundation 層對應的CFReadStreamRef 和 CFWriteStreamRef 的高層抽象。在使用CFNetwork時吆豹,常常會使用到CFReadStreamRef 與 CFWriteStreamRef鱼的。