iOS 之FTP上傳 文件

在日常開發(fā)中,我們都在用http(s) 來進(jìn)行網(wǎng)絡(luò)傳輸?shù)?,上傳下載等任務(wù)的,前段時(shí)間聽說要用ftp來上傳資源,當(dāng)時(shí)還是一臉懵逼的。后來東拼西湊的算是勉強(qiáng)搞定了。

在iOS端的ftp上傳使用的是CFNetWork框架,它處于核心服務(wù)框架中,提供了一個(gè)抽象化的網(wǎng)絡(luò)協(xié)議庫。使用CFNetWork框架中的CFFTPStream類提供的API能夠做很多ftp操作,例如上傳文件、下載文件、下載目錄列表,創(chuàng)建遠(yuǎn)程目錄等等。


其實(shí)ftp無非就是一個(gè)文件流的讀寫操作而已,NSInputStream 和?NSOutputStream 這兩個(gè)操作而已。

>>1、NSInputStream,文件輸入流?

NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:path]; 此處的path 為文件地址,通過該地址獲取一個(gè)二進(jìn)制文件信息

inputStream.delegate = self;????????//// 設(shè)置代理

? ? [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; ? ? ? ?//// 加入到對應(yīng)的runloop中

? ? [inputStream open]; ? ? ? ?//// 打開文件流

//// 對應(yīng)的回調(diào)方法

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {

//// NSStreamEvent 是回調(diào)的類型判斷。NSStreamEventOpenCompleted 表示鏈接成功

///?NSStreamEventHasBytesAvailable ?讀取數(shù)據(jù)

????????????uint8_t buf[1024];

? ? ? ? ? ? unsigned int len = 0;

? ? ? ? ? ? len = (int)[(NSInputStream *)aStream read:buf maxLength:1024];? // 讀取數(shù)據(jù)

- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)len; /// 這個(gè)方法返回實(shí)際讀取的大小

????????????[inputData appendBytes:(const void *)buf length:len];

/// 到此處即可以把數(shù)據(jù)讀取到?inputData 中

/// ?NSStreamEventEndEncountered 讀取完成,,讀取完成后需要移除操作文件流

????????????[aStream close];

? ? ? ? ? ? [aStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

? ? ? ? ? ? aStream = nil;

}

>>2、NSOutputStream,文件輸出流?

????NSURL *url = [NSURL URLWithString:@"ftp://202.105.45.22/defaultPath/testPath/"];

? ? NSString *account =@"testUsername";

? ? NSString *password =@"testPassword";

NSOutputStream *outputStream = CFBridgingRelease(CFWriteStreamCreateWithFTPURL(NULL,(__bridge CFURLRef) url));

[outputStream setProperty:account forKey:(NSString *)kCFStreamPropertyFTPUserName]; ? ?????/// 設(shè)置 username

? ? [outputStream setProperty:password forKey:(NSString *)kCFStreamPropertyFTPPassword]; ? ? ? ?/// 設(shè)置 password

[outputStream setProperty:kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyFTPAttemptPersistentConnection]; ??/// 保證多次鏈接可實(shí)現(xiàn)

[outputStream setProperty:kCFBooleanFalse forKey:(NSString *)kCFStreamPropertyFTPUsePassiveMode]; ?//設(shè)置鏈接模式(主動(dòng)、被動(dòng))(默認(rèn)被動(dòng))

/// 設(shè)置代理,添加到對應(yīng)的runloop ,打開

outputStream.delegate = self;

? ? [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

? ? [outputStream open];

/// 然后待代理回調(diào)中 的?NSStreamEventHasSpaceAvailable下面實(shí)現(xiàn) 直到回掉?NSStreamEventEndEncountered 表示操作完成

????????????uint8_t *readBytes = (uint8_t *)[inputData mutableBytes];

? ? ? ? ? ? readBytes += byteIndex;

? ? ? ? ? ? int data_len = (int)[inputData length];

? ? ? ? ? ? unsigned int len = (data_len - byteIndex >= 1024) ? 1024 : (data_len - byteIndex);

? ? ? ? ? ? uint8_t buf[len];

? ? ? ? ? ? (void)memcpy(buf, readBytes, len);

? ? ? ? ? ? len = (int)[(NSOutputStream *)aStream write:(const uint8_t *)buf maxLength:len];

///?- (NSInteger)write:(const uint8_t *)buffer maxLength:(NSUInteger)len; 這個(gè)方法返回實(shí)際寫入多少數(shù)據(jù)

? ? ? ? ? ? if (len == -1) { ?

?????????????????????NSLog(@"寫入錯(cuò)誤?。。?!");

? ? ? ? ? ? } else if (len == 0){ ?

????????????????????NSLog(@"寫入完成"); ?

????????????}

? ? ? ? ? ? byteIndex += len;


其實(shí)有一個(gè)很好的開源框架,(?FTPManager?),使用很簡單。

下面直接附上代碼

//初始化文件傳輸管理

- (void)initFTPMgr {

? ? ? ? username = @"appftp";

? ? ? ? password = @"Appftp123";

? ? ? ? hostname = @"101.101.101.101";

? ? ? ? self.requestsManager = [[GRRequestsManager alloc] initWithHostname:hostname ?user:username password:password];

//設(shè)置代理

?? ? ? ?self.requestsManager.delegate = self;

}

//創(chuàng)建圖片文件夾

- (void)createImagePathWithPath {

? ? //創(chuàng)建image文件夾

? ? NSString *imageDir = [NSString stringWithFormat:@"/%@/%@/image",self.baseFileDir,self.baseDateStr];

? ? [self.requestsManager addRequestForCreateDirectoryAtPath:imageDir];

? ? [self.requestsManager startProcessingRequests];

? ? NSLog(@"圖片文件夾路徑 %@",imageDir);

}

//準(zhǔn)備上傳文件

- (void)uploadImageWithPath:(NSURL *)url {

? ? NSString *pathExtension = [url pathExtension];

? ? self.uploadName = [NSString stringWithFormat:@"%@.%@",self.guidStr,pathExtension];

//本地文件路徑

?NSString *path = url.path;

//服務(wù)器文件路徑

? ? NSString *toPath = [NSString stringWithFormat:@"%@/%@/image/%@",self.baseFileDir,self.baseDateStr,self.uploadName];

? ? NSLog(@"path = %@ \n toPath = %@",path,toPath);

? ? NSData *data = [NSData dataWithContentsOfFile:path];

? ? NSLog(@"%ld",data.length);

? ? if (data.length > 0) {

//執(zhí)行上傳文件

? ? ? ? [self.requestsManager addRequestForUploadFileAtLocalPath:path toRemotePath:toPath];

? ? ? ? [self.requestsManager startProcessingRequests];

? ? }

}


#pragma mark -- GRRequestsManagerDelegate ? ?//代理方法

// 完成回調(diào)

- (void)requestsManager:(id)requestsManager didCompleteUploadRequest:(id)request

{

? ? //請求工作流接口

? ? [self requestsUploadSuccess];

? ? NSLog(@"requestsManager:didCompleteUploadRequest:");

}

/** 進(jìn)度條回傳 */

- (void)requestsManager:(id)requestsManager didCompletePercent:(float)percent forRequest:(id)request

{

? ? if (self.uploadProgress) {

? ? ? ? self.uploadProgress(percent);

? ? }

}

//失敗回調(diào)

- (void)requestsManager:(id)requestsManager didFailWritingFileAtPath:(NSString *)path forRequest:(id)request error:(NSError *)error

{

? ? NSLog(@"requestsManager:didFailWritingFileAtPath:forRequest:error: \n %@", error);

}

- (void)requestsManager:(id)requestsManager didFailRequest:(id)request withError:(NSError *)error

{

? ? NSLog(@"requestsManager:didFailRequest:withError: \n %@", error);

}


最后附上我感覺好用的FTP庫(?KLFTPHeper?)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容