iOS 之FTP上傳 文件

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

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


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

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

NSInputStream *inputStream = [[NSInputStream alloc] initWithFileAtPath:path]; 此處的path 為文件地址澡刹,通過該地址獲取一個二進(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; /// 這個方法返回實(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è)置鏈接模式(主動嚷闭、被動)(默認(rèn)被動)

/// 設(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; 這個方法返回實(shí)際寫入多少數(shù)據(jù)

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

?????????????????????NSLog(@"寫入錯誤0獭!K急胜蛉!");

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

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

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

? ? ? ? ? ? byteIndex += len;


其實(shí)有一個很好的開源框架挠进,(?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)系作者
  • 序言:七十年代末领突,一起剝皮案震驚了整個濱河市暖璧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌君旦,老刑警劉巖澎办,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘲碱,死亡現(xiàn)場離奇詭異,居然都是意外死亡局蚀,警方通過查閱死者的電腦和手機(jī)麦锯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琅绅,“玉大人扶欣,你說我怎么就攤上這事∏Х觯” “怎么了料祠?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澎羞。 經(jīng)常有香客問我髓绽,道長,這世上最難降的妖魔是什么妆绞? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任顺呕,我火速辦了婚禮,結(jié)果婚禮上括饶,老公的妹妹穿的比我還像新娘塘匣。我一直安慰自己,他們只是感情好巷帝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布忌卤。 她就那樣靜靜地躺著,像睡著了一般楞泼。 火紅的嫁衣襯著肌膚如雪驰徊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天堕阔,我揣著相機(jī)與錄音棍厂,去河邊找鬼。 笑死超陆,一個胖子當(dāng)著我的面吹牛牺弹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播时呀,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼张漂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了谨娜?” 一聲冷哼從身側(cè)響起航攒,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎趴梢,沒想到半個月后漠畜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體币他,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年憔狞,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝴悉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡瘾敢,死狀恐怖辫封,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情廉丽,我是刑警寧澤倦微,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站正压,受9級特大地震影響欣福,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜焦履,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一拓劝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘉裤,春花似錦郑临、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至典奉,卻和暖如春躺翻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卫玖。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工公你, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人假瞬。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓陕靠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親脱茉。 傳聞我的和親對象是個殘疾皇子剪芥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容