Azure功能使用FluentFTP将文件从FTP复制到Blob存储

时间:2019-07-02 08:07:11

标签: c# ftp azure-functions azure-storage-blobs fluentftp

我有一个FTP源,每天都会添加文件,我需要使用天蓝色功能中的FluentFTP库每天将文件从FTP复制到blob存储

我在Azure函数中使用C#,我做了所有编码部分,但是缺少从FTP下载文件以将其直接复制到Blob目标的情况。

//#r "FluentFTP"
#r "Newtonsoft.Json"
#r "System.Data"
#r "Microsoft.WindowsAzure.Storage"

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Globalization;
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;

using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using FluentFTP;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    string blobConnectionString = "ConnectionString";

    // Gestione BLOB Storage
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(blobConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference("out");

    using (FtpClient conn = new FtpClient()) 
    {
        conn.Host = "ftp server";
        conn.Credentials = new NetworkCredential("username", "pass");

        // get a list of files and directories in the "/OUT" folder
        foreach (FtpListItem item in conn.GetListing("/OUT")) 
        {
            // if this is a file and ends with CSV
            if (
            item.Type == FtpFileSystemObjectType.File
            &&
            item.FullName.ToLower().EndsWith(".csv")
            )
            {

                string yyyy = item.FullName.Substring(10,4);
                string mm   = item.FullName.Substring(14,2);
                string dd   = item.FullName.Substring(16,2);
                var fileName = "out/brt/" + yyyy + "/"+ mm + "/"+ dd + "/" + item.Name;

                CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);
                // download the file
                conn.DownloadFile( blockBlob , item.FullName);
            }
        }

        return new OkObjectResult($"Hello");
    }
}

如果我可以将blob容器用作FluentFTP函数的目标,那将是最好的选择,但是这样我会收到一个错误,即我正在使用的blob块不是目标

这是我遇到的错误

  

无法从“ Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob”转换为“字符串”

我不知道是否还有另一种本地下载文件的方法,因此我可以将其上传到Blob,而不是使用此client.DownloadFile函数。

3 个答案:

答案 0 :(得分:2)

使用Fluent FTP可能无法实现。

有一种FtpClient.Download方法采用了Stream

public bool Download(Stream outStream, string remotePath, IProgress<double> progress = null)

但是看起来好像没有API可以获取“大量上传流”

相反,您无法从FluentFTP获得“ “ FTP下载流” (可以与blob API一起使用)。


但是您可以使用本机.NET FtpWebRequest FTP客户端,该客户端具有用于获取“ FTP下载流” 的API:

public static async System.Threading.Tasks.Task RunAsync([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
{
    var ftpUserName = "xxxxxx";
    var ftpPassword = "xxxxxxxxx";
    var filename = "test.png";
    string blobConnectionString = "xxxxxxx";
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(blobConnectionString);
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
    CloudBlobContainer container = blobClient.GetContainerReference("myblobcontainer");
    FtpWebRequest fileRequest = (FtpWebRequest)WebRequest.Create("ftp://xxxxxx/" + filename);
    fileRequest.Method = WebRequestMethods.Ftp.DownloadFile;
    fileRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
    FtpWebResponse fileResponse = (FtpWebResponse)fileRequest.GetResponse();
    Stream fileStream = fileResponse.GetResponseStream();
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(filename);

    await blockBlob.UploadFromStreamAsync(fileStream);
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}

答案 1 :(得分:2)

如果要使用FluentFTP,可以使用以下两种方法之一获取blob上传流:

  1. CloudBlockBlob.OpenWrite()
  2. CloudBlockBlob.OpenWriteAsync()

然后,您可以使用采用FTPClient.Download的{​​{1}}方法

Stream

类似这样的东西:

public bool Download(Stream outStream, string remotePath, IProgress<double> progress = null)

答案 2 :(得分:0)

您不能使用SDK将文件直接从FTP移至Blob。您必须先临时下载文件-要么下载到流(取决于文件的大小),要么下载到临时文件。

但是,如果您要做的只是按计划将文件从FTP移到Blob,我实际上会考虑使用Azure Data Factory,它专门针对以下任务而构建:https://docs.microsoft.com/en-us/azure/data-factory/connector-ftp