swift之向ftp服务器传文件

在 mac 上如何使用 xcode, swift 语言开发一个向 ftp 服务器上传文件的工具?

使用的是第三方库 Rebekka,下载地址为:https://github.com/Constantine-Fry/rebekka。下载完之后直接将所有的 swift 文件拷到项目中即可使用。

 

下面是我自己写的代码 ,首先是 FtpManager.swift 类,封装了上传文件和创建文件夹的方法,代码如下:

//
//  FtpHelper.swift
//  MacFtpUploader
//
//  Created by Jie Tian on 23/3/16.
//  Copyright © 2016 Jie Tian. All rights reserved.
//

import Foundation

public class FtpManager
{
    let m_host:String;
    let m_username:String;
    let m_password:String;
    let m_session:Session;
    
    init (host:String,username:String,password:String,passive:Bool)
    {
        m_host=host;
        m_username=username;
        m_password=password;
        
        var config=SessionConfiguration();
        config.host=host;
        config.username=username;
        config.password=password;
        config.passive=passive;
        
        m_session=Session(configuration: config);
    }
    
    public func UploadFile(srcPath:String,tarPath:String,callback:(Bool) -> Void)
    {
        let localPath=NSURL(fileURLWithPath: srcPath);
        
        m_session.upload(localPath, path: tarPath)
        {
            (succeed,error) -> Void in
            let fullUrl=self.m_host+tarPath;
            if succeed
            {
                print("Upload succeed!
Source path: (localPath)
Target url: (fullUrl)
");
            }
            else
            {
                print("Upload failed...
Error: (error)
Source path: (localPath)
Target url: (fullUrl)
");
            }
            
            callback(succeed);
        };
    }
    
    public func CreateDirectory(path:String)
    {
        m_session.createDirectory(path)
        {
            (succeed, error) -> Void in
            let url=self.m_host+path;
            if succeed
            {
                print("Create directory succeed!
Url: (url)
");
            }
        }
    }
}
FtpManager.swift

下面是程序的入口 main.swift,代码如下:

  1 //
  2 //  main.swift
  3 //  MacFtpUploader
  4 //
  5 //  Created by Jie Tian on 22/3/16.
  6 //  Copyright © 2016 Jie Tian. All rights reserved.
  7 //
  8 
  9 import Foundation
 10 
 11 // 获取 host 所对应的文件夹的 url
 12 func GetHostDirUrls(host:String,inout rootHost:String) -> [String]
 13 {
 14     var urls=[String]();
 15     let words=host.characters.split("/");
 16     let w0Str=String(words[0]);
 17     let w1Str=String(words[1]);
 18     rootHost="(w0Str)//(w1Str)";
 19     
 20     for i in 2..<words.count
 21     {
 22         var url:String=String();
 23         for t in 2...i
 24         {
 25             url+="/"+String(words[t]);
 26         }
 27         urls.append(url);
 28     }
 29     
 30     return urls;
 31 }
 32 
 33 // 传入一个根文件夹路径,取得其所有的文件与文件夹路径
 34 func GetAllFiles(rootDir:String,inout allDirectories:[String],localRootDirName:String) -> [String]
 35 {
 36     let manager=NSFileManager.defaultManager();
 37     let url=NSURL(fileURLWithPath: rootDir);
 38     let contents=manager.enumeratorAtURL(url, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.SkipsHiddenFiles, errorHandler: nil);
 39 
 40     var allFiles=[String]();
 41     allDirectories=[localRootDirName];    // local root dir name must be created first
 42     
 43     for item in contents!
 44     {
 45         var isDir:ObjCBool=ObjCBool(false);
 46         let exists=manager.fileExistsAtPath(item.path, isDirectory:&isDir);
 47         if !exists
 48         {
 49             continue;
 50         }
 51 
 52         if isDir
 53         {
 54             allDirectories.append(item.path);
 55         }
 56         else
 57         {
 58             allFiles.append(item.path);
 59         }
 60     }
 61     
 62     return allFiles;
 63 }
 64 
 65 // 将本地的路径转化为上传的 url
 66 func GetUrl(path:String,absolutePath:String,localRootDirName:String) -> String
 67 {
 68     // 获取 “IOS” 的位置
 69     var rightIndex:String.Index? = nil;
 70     
 71     for i in 0..<path.characters.count
 72     {
 73         if i+localRootDirName.characters.count > path.characters.count
 74         {
 75             continue;
 76         }
 77         
 78         var isRight:Bool=true;
 79         
 80         for k in 0..<localRootDirName.characters.count
 81         {
 82             let c = path[path.startIndex.advancedBy(i+k)];
 83             let tc = localRootDirName[localRootDirName.startIndex.advancedBy(k)];
 84             if c != tc
 85             {
 86                 isRight = false;
 87                 break;
 88             }
 89         }
 90         
 91         if isRight
 92         {
 93             rightIndex = path.startIndex.advancedBy(i);
 94             break;
 95         }
 96     }
 97     
 98     // 拼接 url
 99     return absolutePath+"/"+path.substringFromIndex(rightIndex!);
100 }
101 
102 func Upload(host:String,username:String,password:String,path:String,passive:Bool)
103 {
104     print("Start upload:
host: (host)
username: (username)
password: (password)
path: (path)
passive: (passive)
");
105     
106     // 创建host对应的文件夹
107     var rootHost:String=String();
108     let hostDirUrls=GetHostDirUrls(host,rootHost:&rootHost);
109     let ftp=FtpManager(host:rootHost,username:username,password:password,passive: passive);
110     
111     for hu in hostDirUrls
112     {
113         ftp.CreateDirectory(hu);
114     }
115     
116     let pathDirs=path.characters.split("/");
117     let localRootDirName = String(pathDirs.last!);
118     var allDirs:[String]=[String]();
119     let allFiles=GetAllFiles(path, allDirectories: &allDirs,localRootDirName:localRootDirName);
120     
121     // 创建本地文件需要的文件夹
122     for dp in allDirs
123     {
124         let dirUrl=GetUrl(dp,absolutePath: hostDirUrls.last!,localRootDirName:localRootDirName);
125         ftp.CreateDirectory(dirUrl);
126     }
127     
128     // 上传文件
129     let totalCount=allFiles.count;
130     var uploadedCount=0;
131     
132     for fp in allFiles
133     {
134         let fileUrl=GetUrl(fp,absolutePath: hostDirUrls.last!,localRootDirName:localRootDirName);
135         ftp.UploadFile(fp, tarPath: fileUrl)
136         {
137             (succeed) -> Void in
138             if succeed
139             {
140                 uploadedCount++;
141                 
142                 if uploadedCount >= totalCount
143                 {
144                     print("
All files are uploaded to [(host)] succeed!!!
");
145                 }
146             }
147         }
148     }
149 }
150 
151 // 程序入口
152 func Main()
153 {
154 //    let host="ftp://119.15.139.103/TianJie";
155 //    let username="feixiang.tu";
156 //    let password="feixiang.tu";
157 //    let path="/Users/jie.tian/Documents/BleachMaster/FtpBackup/IOS/";
158     
159 //    let host="ftp://54.223.59.161/Tian/Jie/";
160 //    let username="bleach";
161 //    let password="8c%2rFnlCh&*7$TQqx#UikX";
162 //    let path="/Users/jie.tian/Documents/BleachMaster/FtpBackup/IOS/";
163     
164     // get arguments first
165     let argFilePath=NSBundle.mainBundle().bundlePath+"/MacFtpUploader_Arguments";
166     let argFileUrl=NSURL(fileURLWithPath: argFilePath);
167     let argString=try! NSString(contentsOfURL: argFileUrl, encoding: NSUTF8StringEncoding);
168     let argLines=argString.description.characters.split("
");
169     
170     for l in argLines
171     {
172         let str=String(l);
173         let argWords=str.characters.split(",");
174         let host=String(argWords[1]);
175         let username=String(argWords[2]);
176         let password=String(argWords[3]);
177         let path=String(argWords[0]);
178         let passive=String(argWords[4])=="True";
179         
180         // upload
181         Upload(host,username: username,password: password,path: path,passive: passive);
182     }
183     
184     // delete temp argFile
185     try! NSFileManager.defaultManager().removeItemAtPath(argFilePath);
186     
187     NSRunLoop.mainRunLoop().run();
188 }
189 
190 Main();
main.swift

此 mac 工具是被 unity3d 的一键打包工具调用的,思路是将 shell 命令写在一个文件中,在 c# 中执行此 shell 文件以打开此工具。

shell 命令为,&1 为工具路径,是c#传过来的值:

#!/bin/bash
open $1

调用上面 shell 文件的 c# 代码为:

            if (!IsWindowSystem) 
            {
                string rootPath = string.Format("{0}/Editor/BuildAssetBundle/Tools/", Application.dataPath.TrimEnd('/'));
                
                // save arguments to file
                string tempFilePath = rootPath + "MacFtpUploader_Arguments";
                File.WriteAllText(tempFilePath, sb.ToString());
                
                // invoke tool
                if (File.Exists(tempFilePath))
                {
                    string toolPath = rootPath + "MacFtpUploader";
                    string shell = string.Format("{0}MacFtpUploaderInvoker.sh {1}", rootPath, toolPath);
                    Process.Start("/bin/bash", shell);
                }
                else
                    throw new InvalidOperationException(string.Format("Save arguments to file {0} failed, reupload again please...", tempFilePath));
            }
View Code

运行结果为:

 

xcode 项目附件如下:

http://files.cnblogs.com/files/jietian331/MacFtpUploader.zip

转载请注明出处:http://www.cnblogs.com/jietian331/p/5319357.html

原文地址:https://www.cnblogs.com/jietian331/p/5319357.html