如何在c#cake build中创建一个用FTP上传文件的任务?

use*_*272 5 c# ftp cakebuild

我注意到蛋糕支持HTTP操作,但没有FTP操作,你知道如何通过FTP创建上传文件的任务吗?

dev*_*ead 11

今天Cake中没有任何内置功能可以提供使用FTP协议传输文件的功能.

虽然如果你在"Full CLR"上运行Cake,你可以使用内置的.NET框架FtpWebRequest来上传文件.如果你正在跑步的话,FtpWebRequest还没有被移植到.NET Core这里Cake.CoreCLR.

一种方法是ftp.cake通过使用静态FTPUpload实用程序方法创建一个可以从build.cake文件中重用的方法.

示例ftp.cake

public static bool FTPUpload(
    ICakeContext context,
    string ftpUri,
    string user,
    string password,
    FilePath filePath,
    out string uploadResponseStatus
    )
{
    if (context==null)
    {
        throw new ArgumentNullException("context");
    }

    if (string.IsNullOrEmpty(ftpUri))
    {
        throw new ArgumentNullException("ftpUri");
    }

    if (string.IsNullOrEmpty(user))
    {
        throw new ArgumentNullException("user");
    }

    if (string.IsNullOrEmpty(password))
    {
        throw new ArgumentNullException("password");
    }

    if (filePath==null)
    {
        throw new ArgumentNullException("filePath");
    }

    if (!context.FileSystem.Exist(filePath))
    {
        throw new System.IO.FileNotFoundException("Source file not found.", filePath.FullPath);
    }

    uploadResponseStatus = null;
    var ftpFullPath = string.Format(
        "{0}/{1}",
        ftpUri.TrimEnd('/'),
        filePath.GetFilename()
        );
    var ftpUpload = System.Net.WebRequest.Create(ftpFullPath) as System.Net.FtpWebRequest;

    if (ftpUpload == null)
    {
        uploadResponseStatus = "Failed to create web request";
        return false;
    }

    ftpUpload.Credentials = new System.Net.NetworkCredential(user, password);
    ftpUpload.KeepAlive = false;
    ftpUpload.UseBinary = true;
    ftpUpload.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
    using (System.IO.Stream
        sourceStream = context.FileSystem.GetFile(filePath).OpenRead(),
        uploadStream = ftpUpload.GetRequestStream())
    {
        sourceStream.CopyTo(uploadStream);
        uploadStream.Close();
    }

    var uploadResponse = (System.Net.FtpWebResponse)ftpUpload.GetResponse();
    uploadResponseStatus = (uploadResponse.StatusDescription ?? string.Empty).Trim().ToUpper();
    uploadResponse.Close();
    return  uploadResponseStatus.Contains("TRANSFER COMPLETE") ||
                     uploadResponseStatus.Contains("FILE RECEIVE OK");
}
Run Code Online (Sandbox Code Playgroud)

示例用法build.cake

#load "ftp.cake"

string ftpPath = "ftp://ftp.server.com/test";
string ftpUser = "john";
string ftpPassword = "top!secret";
FilePath sourceFile = File("./data.zip");


Information("Uploading to upload {0} to {1}...", sourceFile, ftpPath);
string uploadResponseStatus;
if (!FTPUpload(
        Context,
        ftpPath,
        ftpUser,
        ftpPassword,
        sourceFile,
        out uploadResponseStatus
    ))
{
    throw new Exception(string.Format(
        "Failed to upload {0} to {1} ({2})",
        sourceFile,
        ftpPath,
        uploadResponseStatus));
}

Information("Successfully uploaded file ({0})", uploadResponseStatus);
Run Code Online (Sandbox Code Playgroud)

示例输出

Uploading to upload log.cake to ftp://ftp.server.com/test...
Successfully uploaded file (226 TRANSFER COMPLETE.)
Run Code Online (Sandbox Code Playgroud)

FtpWebRequest 是非常基本的,所以你可能需要适应你的目标ftp服务器,但上面应该是一个很好的起点.


Gar*_*ark 5

虽然我自己没有尝试过,但我“认为”我说你可以使用这个Cake Addin进行文件传输操作是正确的。绝对值得与插件的原作者谈谈。

如果没有,最好的办法是为 Cake 创建一个自定义插件,它提供您正在寻找的功能。

关于这是否也应将其纳入 Cake 功能的核心集存在疑问,但是,第一个行动方案将是一个插件。

  • Putty 支持 SCP/SFTP 协议,但不支持 FTP。 (2认同)