【转】iphone 输入/输出流异步读写数据

 

原文:iphone 输入/输出流异步读写数据

分类: iphone

1、首先是往文件里写入数据

WriteFile.h

  1. #import <Foundation/Foundation.h>  
  2. #import <UIKit/UIKit.h>  
  3. @class NoteDb;  
  4. @interface WriteFile : NSObject<NSStreamDelegate>{  
  5.     //文件地址  
  6.     NSString *parentDirectoryPath;  
  7.     //输出流,写数据  
  8.     NSOutputStream *asyncOutputStream;  
  9.     //写数据的内容  
  10.     NSData *outputData;  
  11.     //位置及长度  
  12.     NSRange outputRange;  
  13.     //数据的来源  
  14.     NoteDb *aNoteDb;  
  15. }  
  16. @property (nonatomic,retain) NSData *outputData;  
  17. @property (nonatomic,retain) NoteDb *aNoteDb;  
  18. //写数据  
  19. -(void)write;  
  20. @end  

实现文件WriteFile.m
  1. #import "WriteFile.h"  
  2. #import "NoteDb.h"  
  3. @implementation WriteFile  
  4. @synthesize outputData,aNoteDb;  
  5.   
  6. -(id)init{  
  7.     self=[super init];  
  8.     if (!self) {  
  9.         [self release];  
  10.         return nil;  
  11.     }  
  12.     outputData=[[NSData alloc]init];  
  13.     aNoteDb=[[NoteDb alloc]init];  
  14.     return self;  
  15. }  
  16. -(void)write{  
  17.     //NSLog(@"%@",self.aNoteDb);  
  18.     //沙盒路径  
  19.     NSArray *paths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  20.     NSString *documentsDirectory = [paths objectAtIndex:0];  
  21.     //文件名字是note.txt  
  22.     NSString *path = [documentsDirectory stringByAppendingPathComponent:@"note.txt"];  
  23.       
  24.     [asyncOutputStream release];  
  25.     parentDirectoryPath = path;  
  26.     //数据源  
  27.     NSData *tmpdata = [NSKeyedArchiver archivedDataWithRootObject:self.aNoteDb.noteList];  
  28.       
  29.     //self.outputData=[[NSData alloc]initWithData:tmpdata];  
  30.     self.outputData=tmpdata;  
  31.     //位置从哪开始  
  32.     outputRange.location=0;  
  33.     //创建文件  
  34.     [[NSFileManager defaultManager] createFileAtPath:parentDirectoryPath  
  35.                                             contents:nil attributes:nil];  
  36.     //初始化输出流  
  37.     asyncOutputStream = [[NSOutputStream alloc] initToFileAtPath: parentDirectoryPath append: NO];  
  38.     //回调方法,  
  39.     [asyncOutputStream setDelegate: self];   
  40.     //异步处理,  
  41.     [asyncOutputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]  forMode:NSDefaultRunLoopMode];  
  42.     //打开异步输出流  
  43.     [asyncOutputStream open];   
  44.       
  45.       
  46. }  
  47. -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent{  
  48.    // NSLog(@"as");  
  49.     NSOutputStream *outputStream = (NSOutputStream*) theStream;  
  50.     BOOL shouldClose = NO;  
  51.     switch (streamEvent)   
  52.     {  
  53.         case NSStreamEventHasSpaceAvailable://读事件   
  54.         {  
  55.             //缓冲区  
  56.             uint8_t outputBuf [1];  
  57.             //长度  
  58.             outputRange.length = 1;  
  59.             //把数据放到缓冲区中  
  60.             [outputData getBytes:&outputBuf range:outputRange];   
  61.             //把缓冲区中的东西放到输出流  
  62.             [outputStream write: outputBuf maxLength: 1];   
  63.             //判断data数据是否读完  
  64.             if (++outputRange.location == [outputData length])   
  65.             {    
  66.                 shouldClose = YES;  
  67.             }  
  68.             break;  
  69.         }  
  70.         case NSStreamEventErrorOccurred:  
  71.         {  
  72.             //出错的时候  
  73.             NSError *error = [theStream streamError];  
  74.             if (error != NULL)   
  75.             {  
  76.                 UIAlertView *errorAlert = [[UIAlertView alloc]  
  77.                                            initWithTitle: [error localizedDescription]  
  78.                                            message: [error localizedFailureReason]  
  79.                                            delegate:nil  
  80.                                            cancelButtonTitle:@"OK"  
  81.                                            otherButtonTitles:nil];  
  82.                 [errorAlert show];  
  83.                 [errorAlert release];  
  84.             }  
  85.             shouldClose = YES;  
  86.             break;  
  87.         }  
  88.         case NSStreamEventEndEncountered:  
  89.             shouldClose = YES;  
  90.     }  
  91.     if (shouldClose)  
  92.     {  
  93.         //当出错或者写完数据,把线程移除  
  94.         [outputStream removeFromRunLoop: [NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];  
  95.         //最后关掉输出流  
  96.         [theStream close];   
  97.     }  
  98.   
  99. }  
  100. -(void)dealloc{  
  101.     [outputData release];  
  102.     [aNoteDb release];  
  103.     [super dealloc];  
  104. }  
  105. @end  

2、其次是从文件里读出数据

ReadFile.h

  1. #import <Foundation/Foundation.h>  
  2. @class NoteDb;  
  3. @interface ReadFile : NSObject<NSStreamDelegate>{  
  4.     //路径  
  5.     NSString *parentDirectoryPath;  
  6.     //异步输出流  
  7.     NSInputStream *asyncInputStream;  
  8.     //读出来的数据  
  9.     NSMutableData *resultData;  
  10.     //返回去的数据  
  11.     NoteDb *aNoteDb;  
  12. }  
  13. @property(nonatomic,retain)NoteDb *aNoteDb;  
  14. @property (nonatomic, retain) NSMutableData *resultData;  
  15. //开始读数据  
  16. -(void)read;  
  17. //读出来的数据追加到resultData上  
  18. - (void)appendData:(NSData*)_data;  
  19. //  
  20. - (void)dataAtNoteDB;  
  21. //返回去的数据  
  22. - (NoteDb*)getNoteDb;  
  23. @end  

实现文件ReadFile.m
  1. #import "ReadFile.h"  
  2. #import "NoteDb.h"  
  3. #import "NoteList.h"  
  4. #import "WriteFile.h"  
  5. @implementation ReadFile  
  6. @synthesize aNoteDb,resultData;  
  7. -(id)init{  
  8.     self=[super init];  
  9.     //aNoteDb=[[NoteDb alloc]init];  
  10.     resultData=[[NSMutableData alloc]init];  
  11.     return self;  
  12. }  
  13. -(void)read{  
  14.     //沙盒路径  
  15.     NSArray *paths= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
  16.     NSString *documentsDirectory = [paths objectAtIndex:0];  
  17.     //文件名  
  18.     NSString *path = [documentsDirectory stringByAppendingPathComponent:@"note.txt"];  
  19.     /* 
  20.     if(![[NSFileManager defaultManager]fileExistsAtPath:path]){ 
  21.         //如果不存在,就新建 
  22.         WriteFile *file=[[WriteFile alloc]init]; 
  23.         [file write]; 
  24.         [file release];         
  25.     }else{ 
  26.         NSLog(@"有note.txt文件"); 
  27.     } 
  28.     */  
  29.     [asyncInputStream release];  
  30.     parentDirectoryPath = path;  
  31.     //异步输入流初始化,并把赋于地址  
  32.     asyncInputStream =  
  33.     [[NSInputStream alloc] initWithFileAtPath: parentDirectoryPath];  
  34.     //设置代理(回调方法、委托)  
  35.     [asyncInputStream setDelegate: self];  
  36.     //设置线程,添加线程,创建线程:Runloop顾名思义就是一个不停的循环,不断的去check输入  
  37.     [asyncInputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]  
  38.                                 forMode:NSDefaultRunLoopMode];  
  39.     //打开线程  
  40.     [asyncInputStream open];  
  41.   
  42. }  
  43. //追加数据  
  44. - (void)appendData:(NSData*)_data{  
  45.     [resultData appendData:_data];  
  46. }  
  47. //回调方法,不停的执行  
  48. -(void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent{  
  49.     BOOL shouldClose = NO;  
  50.     NSInputStream *inputStream = (NSInputStream*) theStream;  
  51.      //NSLog(@"as");  
  52.     switch (streamEvent)   
  53.     {  
  54.         case NSStreamEventHasBytesAvailable:   
  55.         {         
  56.             //读数据  
  57.             //读取的字节长度  
  58.             NSInteger maxLength = 128;   
  59.             //缓冲区  
  60.             uint8_t readBuffer [maxLength];   
  61.             //从输出流中读取数据,读到缓冲区中  
  62.             NSInteger bytesRead = [inputStream read: readBuffer   
  63.                                           maxLength:maxLength];  
  64.             //如果长度大于0就追加数据  
  65.             if (bytesRead > 0)   
  66.             {  
  67.                 //把缓冲区中的数据读成data数据   
  68.                 NSData *bufferData = [[NSData alloc]  
  69.                                       initWithBytesNoCopy:readBuffer   
  70.                                       length:bytesRead   
  71.                                       freeWhenDone:NO];  
  72.                 //追加数据  
  73.                 [self appendData:bufferData];  
  74.                 //release掉data  
  75.                 [bufferData release];  
  76.             }  
  77.             break;  
  78.         }   
  79.         case NSStreamEventErrorOccurred:   
  80.         {  
  81.             //读的时候出错了  
  82.             NSError *error = [theStream streamError];  
  83.             if (error != NULL)   
  84.             {  
  85.                 UIAlertView *errorAlert = [[UIAlertView alloc]  
  86.                                            initWithTitle: [error localizedDescription]  
  87.                                            message: [error localizedFailureReason]  
  88.                                            delegate:nil  
  89.                                            cancelButtonTitle:@"OK"  
  90.                                            otherButtonTitles:nil];  
  91.                 [errorAlert show];  
  92.                 [errorAlert release];  
  93.             }  
  94.             shouldClose = YES;  
  95.             break;  
  96.         }  
  97.         case NSStreamEventEndEncountered:   
  98.         {  
  99.             shouldClose = YES;  
  100.             //数据读完就返回数据  
  101.             [self dataAtNoteDB];              
  102.             [theStream close];  
  103.         }break;  
  104.     }  
  105.     if (shouldClose)  
  106.     {  
  107.         //当文件读完或者是读到出错时,把线程移除  
  108.         [inputStream removeFromRunLoop: [NSRunLoop currentRunLoop]   
  109.                                forMode:NSDefaultRunLoopMode];  
  110.         //并关闭流  
  111.         [theStream close];   
  112.     }  
  113. }  
  114. -(void) dataAtNoteDB{  
  115.     aNoteDb=nil;  
  116.     aNoteDb=[[NoteDb alloc]init];  
  117.     aNoteDb.noteList = [NSKeyedUnarchiver unarchiveObjectWithData:resultData];  
  118.     //NSLog(@"%@",aNoteDb);  
  119.     /* 
  120.     for (id tmp in  aNoteDb.noteList.noteArray)  
  121.     { 
  122.         NSLog(@"tmp = %@",tmp); 
  123.     } 
  124.      */  
  125. }  
  126. - (NoteDb*)getNoteDb{  
  127.     return self.aNoteDb;  
  128. }  
  129. -(void)dealloc{  
  130.     [aNoteDb release];  
  131.     [resultData release];  
  132.     [super dealloc];  
  133. }  
  134. @end  
原文地址:https://www.cnblogs.com/wangrui-techbolg/p/3965105.html