Функция Azure для копирования файлов с FTP в хранилище BLOB-объектов с помощью FluentFTP - PullRequest
1 голос
/ 02 июля 2019

У меня есть источник FTP, который добавляет ежедневный файл, и мне нужно ежедневно копировать файлы с FTP в хранилище больших двоичных объектов с использованием библиотеки FluentFTP в функции Azure

Я использую C # в функции Azure, и я сделалвся часть кода, но не хватает для загрузки файла с 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, тогда это будет лучшим, но таким образом я получаю сообщение об ошибке, что этот блок блоба, который я использую, не является местом назначения

Это ошибка, которую я получаю

не может преобразовать из 'Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob 'to' string '

Я не знаю, есть ли другой способ загрузить файл локально, чтобы я мог загрузить его в BLOB-объект вместо использования этого client.DownloadFile функция.

Ответы [ 2 ]

2 голосов
/ 02 июля 2019

Вероятно, это невозможно с Fluent FTP.

Есть FtpClient.Download метод, который принимает Stream.

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

Но не похоже, что есть API для получения «Поток загрузки BLOB-объектов» .

И наоборот, вы не можете получить «Поток загрузки по FTP» от FluentFTP (который вы можете использовать с API-интерфейсом BLOB-объектов).


Но вы можете использовать собственный FTP-клиент .NET FtpWebRequest, который имеет API для получения "потока загрузки по FTP" :

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}");
}
0 голосов
/ 02 июля 2019

Вы не можете напрямую переместить файлы с FTP на Blob с помощью SDK.Сначала необходимо временно загрузить файлы - либо в поток (в зависимости от их размера), либо во временный файл.

Однако, если вам нужно только переместить файлы с FTP на Blob напо расписанию, я бы на самом деле изучил использование фабрики данных Azure, которая создана именно для таких задач: https://docs.microsoft.com/en-us/azure/data-factory/connector-ftp

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...