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

时间:2018-04-16 07:33:02

标签: c# asp.net .net azure azure-storage

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

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

2 个答案:

答案 0 :(得分:1)

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

  1. WebClient类将文件从blob存储下载到本地驱动器
  2. FTP库,如WinSCP移动文件
  3. 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代码。

答案 1 :(得分:1)

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

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

这使我可以将文件直接从Blob存储传输到FTP客户端。对我来说,基于Blob触发器创建Azure函数时,已经完成了将Azure Blob文件作为流的操作。

然后我将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());
            }
        }
    }