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

Posted

技术标签:

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

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

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

【问题讨论】:

【参考方案1】:

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

    WebClient 类将文件从 blob 存储下载到本地驱动器 用于移动文件的 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());
            
        
    

【讨论】:

只要文件大小小于配置的内存就可以使用,否则你会炸毁你的内存并且任务会失败 不确定这如何最终出现在质量非常低的队列中 - 这似乎是为了回答这个问题而做出的善意努力。是否正确答案是投票的问题。

以上是关于将文件从 Azure 存储 blob 移动到 Ftp 服务器的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript Azure Blob 存储移动 blob

何时使用 Azure Blob 存储与 Azure 文件共享?

将数据从数据库移动到 Azure Blob 存储

使用 Nodejs 将文件从 Azure 存储 blob(容器)复制到 Azure 文件共享

当文件上传到 azure 文件共享时,如何添加触发器以将文件从 azure 文件共享移动到 azure blob?

Azure 数据湖:将数据从 Blob 移动到 ADLS 时面临问题