将文件从Azure存储blob移动到Ftp服务器

问题描述 投票:0回答:2

我需要将几个文件从Azure存储上传到外部Ftp服务器。

有没有办法让Azure直接上传这些文件而不先下载它们?

c# asp.net .net azure azure-storage
2个回答
1
投票

您将需要使用两个类/库并在此处创建两个方法:

  1. WebClient类将文件从blob存储下载到本地驱动器
  2. FTP库这样的WinSCP来移动文件

WebClient类:您需要提供URI参数,格式为:https://[accountname].blob.core.windows.net/[containername]/[filetodownloadincludingextension]

然后,下载位置必须是变量,作为要上载到FTP服务器的文件的起始位置。

        string uri = "https://[accountname].blob.core.windows.net/[containername]/[filetodownloadincludingextension]/";
        string file = "file1.txt";
        string downloadLocation = @"C:\";

        WebClient webClient = new WebClient();
        Log("Downloading File from web...");
        try
        {
            webClient.DownloadFile(new Uri(uri+file), downloadLocation);
            Log("Download from web complete");
            webClient.Dispose();
        }
        catch (Exception ex)
        {
            Log("Error Occurred in downloading file. See below for exception details");
            Log(ex.Message);
            webClient.Dispose();
        } 
        return downloadLocation + file;

下载到本地驱动器后,需要将其上传到FTP / SFTP服务器。您可以使用WinSCP库来实现此目的:

        string absPathSource = downloadLocation + file;
        string destination = "/root/folder"; //this basically is your FTP path

    // Setup session options
        SessionOptions sessionOptions = new SessionOptions
        {

            Protocol = Protocol.Sftp,
            HostName = ConfigurationManager.AppSettings["scpurl"],
            UserName = ConfigurationManager.AppSettings["scpuser"],
            Password = ConfigurationManager.AppSettings["scppass"].Trim(),
            SshHostKeyFingerprint = ConfigurationManager.AppSettings["scprsa"].Trim()
        };

        using (Session session = new Session())
        {

            //disable version checking
            session.DisableVersionCheck = true;

            // Connect
            session.Open(sessionOptions);

            // Upload files
            TransferOptions transferOptions = new TransferOptions();
            transferOptions.TransferMode = TransferMode.Binary;

            TransferOperationResult transferResult;
            transferResult = session.PutFiles(absPathSource, destination, false, transferOptions);

            // Throw on any error
            transferResult.Check();

            // Print results
            foreach (TransferEventArgs transfer in transferResult.Transfers)
            {
                //Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
            }
        }

如果要在上载后从本地硬盘驱动器中删除该文件,则可以在上载结束时在FTP代码中包含File.Delete代码。


0
投票

我在寻找相同的答案时遇到了这个问题,我提出了以下解决方案:

  • 获取Azure文件作为流[由Azure函数处理]
  • 使用WebClient上传流

这允许我将文件直接从Blob存储传输到FTP客户端。对我来说,作为Stream的Azure Blob文件已经完成,因为我正在创建基于blob触发器的Azure功能。

然后我将Stream转换为MemoryStream并将其作为字节数组传递给WebClient.UploadData()[非常类似]:

// ... Get the Azure Blob file in to a Stream called myBlob
// As mentioned above the Azure function does this for you:
// public static void Run([BlobTrigger("containerName/{name}", Connection = "BlobConnection")]Stream myBlob, string name, ILogger log)

public void UploadStreamToFtp(Stream file, string targetFilePath)
    {
        using (MemoryStream ms = new MemoryStream())
        {
            // As memory stream already handles ToArray() copy the Stream to the MemoryStream
            file.CopyTo(ms);

            using (WebClient client = new WebClient())
            {
                // Use login credentails if required
                client.Credentials = new NetworkCredential("username", "password");

                // Upload the stream as Data with the STOR method call
                // targetFilePath is a fully qualified filepath on the FTP, e.g. ftp://targetserver/directory/filename.ext
                client.UploadData(targetFilePath, WebRequestMethods.Ftp.UploadFile, ms.ToArray());
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.