下面是我之前写的FTP上传图片的类
#import <Foundation/Foundation.h>
#include <CFNetwork/CFNetwork.h>
enum {
kSendBufferSize = 32768
};
@protocol updateHeadImage <NSObject>
- (void)updateHeadImageSuccess:(BOOL )success;
@end
@interface FTPEngine : NSObject <NSStreamDelegate>
{
uint8_t _buffer[kSendBufferSize];
}
@property (nonatomic, retain)NSArray *pathArr;
@property (nonatomic, assign)NSInteger p;
+ (FTPEngine *)sharedEngine;
- (void)sendImagefilePath:(NSString *)imageFilePath :(NSInteger)i;
@property (nonatomic,weak) id<updateHeadImage>delegate;
@end
#import "FTPEngine.h"
@interface FTPEngine ()
//内部变量
@property (nonatomic, readonly) BOOL isSending;
@property (nonatomic, retain) NSOutputStream * networkStream;
@property (nonatomic, retain) NSInputStream * fileStream;
@property (nonatomic, readonly) uint8_t * buffer;
@property (nonatomic, assign) size_t bufferOffset;
@property (nonatomic, assign) size_t bufferLimit;
@property (nonatomic ,assign)NSInteger q;
@end
@implementation FTPEngine
+ (FTPEngine *)sharedEngine
{
static FTPEngine *engine = nil;
static dispatch_once_t once;
dispatch_once(&once, ^{
engine = [[FTPEngine alloc] init];
});
return engine;
}
- (uint8_t *)buffer
{
return self->_buffer;
}
- (void)sendImagefilePath:(NSString *)imageFilePath :(NSInteger)i
{
self.q = i;
NSURL *url;//ftp服务器地址
NSString *filePaths;//图片地址
NSString *account;//账号
NSString *password;//密码
CFWriteStreamRef ftpStream;
filePaths = imageFilePath;
account = @"ftp";
password = @"123456";
if (i == 0)
{
url = [NSURL URLWithString:@"ftp://192.168.1.188:21/emot"];
}
else if (i == 1)
{
url = [NSURL URLWithString:@"ftp://192.168.1.188:21/product"];
}
else if (i == 2)
{
url = [NSURL URLWithString:@"ftp://192.168.1.188:21/idcard"];
}
//添加后缀(文件名称)
url = (__bridge NSURL *)(CFURLCreateCopyAppendingPathComponent(NULL, (CFURLRef) url, (CFStringRef) [filePaths lastPathComponent], false));
//读取文件,转化为输入流
self.fileStream = [NSInputStream inputStreamWithFileAtPath:filePaths];
[self.fileStream open];
//为url开启CFFTPStream输出流
ftpStream = CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url);
self.networkStream = (__bridge NSOutputStream *) ftpStream;
//设置ftp账号密码
[self.networkStream setProperty:account forKey:(id)kCFStreamPropertyFTPUserName];
[self.networkStream setProperty:password forKey:(id)kCFStreamPropertyFTPPassword];
//设置networkStream流的代理,任何关于networkStream的事件发生都会调用代理方法
self.networkStream.delegate = self;
//设置runloop
[self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.networkStream open];
//完成释放链接
CFRelease(ftpStream);
}
#pragma mark 回调方法
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
//aStream 即为设置为代理的networkStream
switch (eventCode) {
case NSStreamEventOpenCompleted: {
} break;
case NSStreamEventHasBytesAvailable: {
assert(NO); // 在上传的时候不会调用
} break;
case NSStreamEventHasSpaceAvailable: {
if (self.bufferOffset == self.bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.fileStream read:self.buffer maxLength:kSendBufferSize];
if (bytesRead == -1) {
//读取文件错误
[self _stopSendWithStatus:@"读取文件错误"];
} else if (bytesRead == 0) {
//文件读取完成 上传完成
[self _stopSendWithStatus:nil];
} else {
self.bufferOffset = 0;
self.bufferLimit = bytesRead;
}
}
if (self.bufferOffset != self.bufferLimit)
{
//写入数据
NSInteger bytesWritten;//bytesWritten为成功写入的数据
bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
assert(bytesWritten != 0);
if (bytesWritten == -1) {
[self _stopSendWithStatus:@"网络写入错误"];
} else {
self.bufferOffset += bytesWritten;
}
}
} break;
case NSStreamEventErrorOccurred: {
[self _stopSendWithStatus:@"Stream打开错误"];
assert(NO);
} break;
case NSStreamEventEndEncountered: {
// 忽略
} break;
default: {
assert(NO);
} break;
}
}
//结果处理
- (void)_stopSendWithStatus:(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;
}
[self _sendDidStopWithStatus:statusString];
}
- (void)_sendDidStopWithStatus:(NSString *)statusString
{
if (statusString == nil)
{
NSLog(@"上传成功!!!");
if (self.p < self.pathArr.count)
{
[self sendImagefilePath:self.pathArr[self.p] :self.q];
self.p = self.p + 1;
}
else
{
if ([self.delegate respondsToSelector:@selector(updateHeadImageSuccess:)]) {
[self.delegate updateHeadImageSuccess:YES];
return;
}
}
}
if ([self.delegate respondsToSelector:@selector(updateHeadImageSuccess:)]) {
[self.delegate updateHeadImageSuccess:NO];
}
}
@end