【发布时间】:2018-09-25 20:49:22
【问题描述】:
我需要将一些文件从 Azure 存储上传到外部 Ftp 服务器。
Azure 有什么方法可以直接上传这些文件而无需先下载它们?
【问题讨论】:
标签: c# asp.net .net azure azure-storage
我需要将一些文件从 Azure 存储上传到外部 Ftp 服务器。
Azure 有什么方法可以直接上传这些文件而无需先下载它们?
【问题讨论】:
标签: c# asp.net .net azure azure-storage
您将需要使用两个类/库并在此处创建两个方法:
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 代码。
【讨论】:
我在寻找相同答案时遇到了这个问题,我想出了以下解决方案:
这使我可以将文件直接从 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());
}
}
}
【讨论】: