前些天看了下IOS苹果关于FTP上传下载的官方例子,说实话,真心不好用,各种问题,所以用CURL自己写了个上传下载的小demo
只需填入相关的参数即可完成下载,如果想要添加其他功能也可以在库中找找其它对应参数写进去。
关于CURL的苹果用的库可以在这里下载http://curl.haxx.se/download.html,
将security和libz两个库也要倒入到工程,再将targets里面的searchPaths改为YES并填入正确的.h文件地址就可以了
上传
#import <Foundation/Foundation.h>
#include "curl/curl.h"
@protocol CURLUploadDelegate <NSObject>
-(void)uploadSuccess;
-(void)uploadFailed;
@end
@interface CURLUpload : NSObject
@property (assign , nonatomic) id<CURLUploadDelegate> delegate;
-(void)uploadFTPFileWith:(NSString*)FTPPath localPath:(NSString*)localPath userName:(NSString*)userName passWord:(NSString*)passWord hostAdress:(NSString*)hostAdress;
@end
#import "CURLUpload.h"
@implementation CURLUpload
@synthesize delegate;
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
curl_off_t nread;
/* in real-world cases, this would probably get this data differently
as this fread() stuff is exactly what the library already would do
by default internally */
size_t retcode = fread(ptr, size, nmemb, stream);
nread = (curl_off_t)retcode;
fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T
" bytes from file\n", nread);
return retcode;
}
-(void)uploadFTPFileWith:(NSString*)FTPPath localPath:(NSString*)localPath userName:(NSString*)userName passWord:(NSString*)passWord hostAdress:(NSString*)hostAdress{
CURL *curl;
CURLcode res;
FILE *hd_src;
NSString *fileFTPAdress;
// = [NSString stringWithFormat:@"ftp://%@/%@",hostAdress,FTPPath];
if ([[FTPPath substringToIndex:1] isEqualToString:@"/"]) {
fileFTPAdress = [NSString stringWithFormat:@"ftp://%@%@",hostAdress,FTPPath];
}
else{
fileFTPAdress = [NSString stringWithFormat:@"ftp://%@/%@",hostAdress,FTPPath];
}
NSString *userNamePassword = [NSString stringWithFormat:@"%@:%@",userName,passWord];
struct stat file_info;
curl_off_t fsize;
struct curl_slist *headerlist=NULL;
// static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
// static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
/* get the file size of the local file */
// if(stat(LOCAL_FILE, &file_info)) {
// printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
//
// }
// fsize = (curl_off_t)file_info.st_size;
//
// printf("Local file size: %" CURL_FORMAT_CURL_OFF_T " bytes.\n", fsize);
/* get a FILE * of the same file */
// NSString *filename = [NSString stringWithFormat:@"%@/第1集:课程介绍.mp4",[self localPortraitPath]];
hd_src = fopen(localPath.UTF8String, "rb");
/* In windows, this will init the winsock stuff */
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if(curl) {
/* build a list of commands to pass to libcurl */
// headerlist = curl_slist_append(headerlist, buf_1);
// headerlist = curl_slist_append(headerlist, buf_2);
/* we want to use our own read function */
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
/* enable uploading */
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
/* specify target */
curl_easy_setopt(curl,CURLOPT_URL,fileFTPAdress.UTF8String);
/* pass in that last of FTP commands to run after the transfer */
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
/* now specify which file to upload */
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
curl_easy_setopt(curl, CURLOPT_USERPWD, userNamePassword.UTF8String); //FTP登陆账号密码,模拟登陆
/* Set the size of the file to upload (optional). If you give a *_LARGE
option you MUST make sure that the type of the passed-in argument is a
curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
make sure that to pass in a type 'long' argument. */
// curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
// (curl_off_t)fsize);
/* Now run off and do what you've been told! */
res = curl_easy_perform(curl);
/* Check for errors */
if(res != CURLE_OK){
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
if ([delegate respondsToSelector:@selector(uploadFailed)]) {
[delegate performSelector:@selector(uploadFailed)];
}
}
else{
if ([delegate respondsToSelector:@selector(uploadSuccess)]) {
[delegate performSelector:@selector(uploadSuccess)];
}
}
/* clean up the FTP commands list */
curl_slist_free_all (headerlist);
/* always cleanup */
curl_easy_cleanup(curl);
}
fclose(hd_src); /* close the local file */
curl_global_cleanup();
}
@end
@protocol CurlDownloadDelegate <NSObject>
-(void)downloadSuccessCallBack;
-(void)downloadFaildCallBack;
@end
@interface CURLDownload : NSObject
@property (assign, nonatomic) id<CurlDownloadDelegate> delegate;
-(void)downloadFTPFileWith:(NSString*)FTPPath localPath:(NSString*)localPath userName:(NSString*)userName passWord:(NSString*)passWord hostAdress:(NSString*)hostAdress ;
@end
#import "CURLDownload.h"
@implementation CURLDownload
@synthesize delegate;
struct FtpFile {
const char *filename;
FILE *stream;
};
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct FtpFile *out=(struct FtpFile *)stream;
if(out && !out->stream) {
/* open file for writing */
out->stream=fopen(out->filename, "wb");
if(!out->stream)
return -1; /* failure, can't open file to write */
}
return fwrite(buffer, size, nmemb, out->stream);
}
-(void)downloadFTPFileWith:(NSString*)FTPPath localPath:(NSString*)localPath userName:(NSString*)userName passWord:(NSString*)passWord hostAdress:(NSString*)hostAdress {
CURL *curl;
CURLcode res;
// NSString *filename = [NSString stringWithFormat:@"%@/myPortrait.mp4",[self localPortraitPath]];
NSString *fileFTPAdress;
if ([[FTPPath substringToIndex:1] isEqualToString:@"/"]) {
fileFTPAdress = [NSString stringWithFormat:@"ftp://%@%@",hostAdress,FTPPath];
}
else{
fileFTPAdress = [NSString stringWithFormat:@"ftp://%@/%@",hostAdress,FTPPath];
}
NSString *userNamePassword = [NSString stringWithFormat:@"%@:%@",userName,passWord];
struct FtpFile ftpfile={
localPath.UTF8String, /* name to store the file as if succesful */
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if(curl) {
/*
* You better replace the URL with one that works!
*/
curl_easy_setopt(curl, CURLOPT_URL,
fileFTPAdress.UTF8String);
/* Define our callback to get called when there's data to be written */
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
/* Set a pointer to our struct to pass to the callback */
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
/* Switch on full protocol/debug output */
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_USERPWD, userNamePassword.UTF8String); //FTP登陆账号密码,模拟登陆
res = curl_easy_perform(curl);
/* always cleanup */
curl_easy_cleanup(curl);
if(CURLE_OK != res) {
/* we failed */
fprintf(stderr, "curl told us %d\n", res);
if ([delegate respondsToSelector:@selector(downloadFaildCallBack)]) {
[delegate performSelector:@selector(downloadFaildCallBack)];
}
}
else{
if ([delegate respondsToSelector:@selector(downloadSuccessCallBack)]) {
[delegate performSelector:@selector(downloadSuccessCallBack)];
}
}
}
if(ftpfile.stream)
fclose(ftpfile.stream); /* close the local file */
curl_global_cleanup();
}
@end