iOS ftp下载

上一篇文章分析了ftp的上传原理,本文接着介绍ftp的下载,ftp下载使用的是Anonymous FTP ,即匿名的ftp,可以用它下载一些公共的文件,而不需要输入账号密码。

【传送门】:iOS ftp上传

http://blog.csdn.net/yang8456211/article/details/12451013


一、简介

        在iOS端的ftp下载使用的也是CFNetWork框架中的CFFTPStreamAPI,不赘述了,在iOS ftp上传里面有较细的描述。


二、配置

1) 建立SingleView项目,取名为FtpDownLoad,导入CFNetWork 框架。

第一步:

第二步:


2) 配置nib文件

iOS ftp下载_第1张图片

包括:

  • 服务器地址输入框
  • 下载按钮
  • 下载状态显示区
  • 图片显示区

当下载完成之后,我们会用从本地读取图片显示。


三、核心代码

1)YGViewController.h(根控制器)

#import <UIKit/UIKit.h>
@interface YGViewController : UIViewController <UITextFieldDelegate,NSStreamDelegate>
@property (retain, nonatomic) IBOutlet UITextField *serverInput;
@property (retain, nonatomic) IBOutlet UILabel *status;
@property (retain, nonatomic) IBOutlet UIImageView *imageView;
- (IBAction)downLoadAction:(id)sender;//下载事件
- (IBAction)didEndEditing:(id)sender;//关闭键盘
@end

使用CFFTPStream进行下载,首先要遵循NSStreamDelegate协议。并实现协议中的委托方法。

下面为NSStreamDelegate协议的内容。

@protocol NSStreamDelegate <NSObject>

@optional

- (void)stream:(NSStream *)aStreamhandleEvent:(NSStreamEvent)eventCode;

@end


参数:

aStream

The stream on which eventCode occurred.(即委托的Stream,任何关于此Stream的事件发生都会调用此方法)

eventCode

The stream event that occurred(Stream发生的事件,例如打开、传输数据等)


2)YGViewController.m

声明变量与getter、setter

@interface YGViewController ()
//声明内部变量
@property (nonatomic, retain)   NSInputStream *   networkStream;//输入流
@property (nonatomic, copy)     NSString *        filePath;//文件路径
@property (nonatomic, retain)   NSOutputStream *  fileStream;//输出流

@end
//getter、setter
@implementation YGViewController
@synthesize serverInput = _serverInput;
@synthesize status = _status;
@synthesize imageView = _imageView;

点击下载触发的事件

#pragma mark 点击下载按钮
- (IBAction)downLoadAction:(id)sender {
    CFReadStreamRef ftpStream;
    NSURL *url;
    
    //获得地址
    url = [NSURL URLWithString:_serverInput.text];

    NSLog(@"url is %@",url);

    // 为文件存储路径打开流,filePath为文件写入的路径,hello为图片的名字,具体可换成自己的路径
    self.filePath = @"/Users/yangguang/Desktop/hello.png";
    self.fileStream = [NSOutputStream outputStreamToFileAtPath:self.filePath append:NO];
    [self.fileStream open];
        
    // 打开CFFTPStream
    ftpStream = CFReadStreamCreateWithFTPURL(NULL, (CFURLRef) url);
    self.networkStream = (NSInputStream *) ftpStream;
    assert(ftpStream != NULL);
    
    // 设置代理
    self.networkStream.delegate = self;
    
    // 启动循环
    [self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [self.networkStream open];

	//释放链接
    CFRelease(ftpStream);
}

self.networkStream.delegate =self;的意思是设置networkStream为NSStreamDelegate协议中的代理,即回调方法中的“aStream”。

关于delegate的介绍请看:http://blog.csdn.net/yang8456211/article/details/11542455


回调方法:

#pragma mark NSStreamDelegate委托方法
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
    switch (eventCode) {
        case NSStreamEventOpenCompleted: {
        } break;
        case NSStreamEventHasBytesAvailable: {
            NSInteger bytesRead;
            uint8_t buffer[32768];//缓冲区的大小 32768可以设置,uint8_t为一个字节大小的无符号int类型
            
            // 读取数据
            bytesRead = [self.networkStream read:buffer maxLength:sizeof(buffer)];
            if (bytesRead == -1) {
                [self _stopReceiveWithStatus:@"读取网络数据出错"];
            } else if (bytesRead == 0) {
                //下载成功
                [self _stopReceiveWithStatus:nil];
            } else {
                NSInteger   bytesWritten;//实际写入数据
                NSInteger   bytesWrittenSoFar;//当前数据写入位置
                
                // 写入文件
                bytesWrittenSoFar = 0;
                do {
                    bytesWritten = [self.fileStream write:&buffer[bytesWrittenSoFar] maxLength:bytesRead - bytesWrittenSoFar];
                    assert(bytesWritten != 0);
                    if (bytesWritten == -1) {
                        [self _stopReceiveWithStatus:@"文件写入出错"];
                        assert(NO);
                        break;
                    } else {
                        bytesWrittenSoFar += bytesWritten;
                    }
                } while (bytesWrittenSoFar != bytesRead);
            }
        } break;
        case NSStreamEventHasSpaceAvailable: {
            assert(NO);     
        } break;
        case NSStreamEventErrorOccurred: {
            [self _stopReceiveWithStatus:@"打开出错,请检查路径"];
            assert(NO);
        case NSStreamEventEndEncountered: {
        } break;
        default:
            assert(NO);
            break;
        }
}
}

bytesWritten是实际写入的数据,每次写入的数据不固定,因此需要bytesWrittenSoFar变量来定位到上次写入数据的位置。

 

 

结果处理:

关闭链接,从filePath中读取图片信息并显示。

#pragma mark 结果处理,关闭链接
- (void)_stopReceiveWithStatus:(NSString *)statusString
{
    if (self.networkStream != nil) {
        [self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.networkStream.delegate = nil;
        [self.networkStream close];
        self.networkStream = nil;
    }
    if (self.fileStream != nil) {
        [self.fileStream close];
        self.fileStream = nil;
    }
    if(statusString == nil){
        statusString = @"下载成功";
        _imageView.image = [UIImage imageWithContentsOfFile:self.filePath];//显示图片
    }
    self.status.text = statusString;
    
    self.filePath = nil;
}

demo下载地址:

http://download.csdn.net/detail/yang8456211/6374441


atany原创,转载请注明博主与博文链接,未经博主允许,禁止任何商业用途。

博文地址:http://blog.csdn.net/yang8456211/article/details/12524669

博客地址:http://blog.csdn.net/yang8456211

—— by atany



你可能感兴趣的:(ios,ios,ios,ios,ios,ftp,下载,ftp下载,ftp下载文件,ftp下载图片)