【问题标题】:Move files from Azure Storage blob to an Ftp server将文件从 Azure 存储 blob 移动到 Ftp 服务器
【发布时间】:2018-09-25 20:49:22
【问题描述】:

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

Azure 有什么方法可以直接上传这些文件而无需先下载它们?

【问题讨论】:

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


    【解决方案1】:

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

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

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

    的 URI 参数

    然后,下载位置必须是一个变量,作为要上传到您的 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 代码。

    【讨论】:

      【解决方案2】:

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

      • 以流形式获取 Azure 文件 [由 Azure Functions 为您处理]
      • 使用 WebClient 上传流

      这使我可以将文件直接从 Blob 存储传输到 FTP 客户端。对我来说,作为流的 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());
                  }
              }
          }
      

      【讨论】:

      • 只要文件大小小于配置的内存就可以使用,否则你会炸毁你的内存并且任务会失败
      • 不确定这如何最终出现在质量非常低的队列中 - 这似乎是为了回答这个问题而做出的善意努力。是否正确答案是投票的问题。
      猜你喜欢
      • 2017-01-19
      • 2017-08-18
      • 1970-01-01
      • 2022-01-18
      • 2021-11-28
      • 2017-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多