首页 > 解决方案 > 在 C# 中将文件从 FTP 直接传输到 Azure Blob 存储

问题描述

我编写了一个将文件从 FTP 服务器移动到 Azure Blob 存储的函数。我想将流从 FTP 传递到 blob,以便我可以上传文件。我正在为每个文件运行一个 while 循环,并尝试使用UploadFromStreamAsync(). 但是当我来这个电话时,我的流对象被释放,因为哪个文件正在传输到 blob 但没有任何内容。在传输所有文件之前,我不想处置我的流对象。谁能告诉我这是怎么回事??

public static async Task FTP_TO_BLOB_TRANSFER()
{
    string ftpPath = ConfigurationSettings.AppSettings.Get("ftpPath");
    string ftpUserName = ConfigurationSettings.AppSettings.Get("ftpUserName");
    string ftpPassword = ConfigurationSettings.AppSettings.Get("ftpPassword");

    FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpPath);
    request.Method = WebRequestMethods.Ftp.ListDirectory;
    request.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
    FtpWebResponse response = (FtpWebResponse)request.GetResponse();
    Stream responseStream = response.GetResponseStream();
    StreamReader reader = new StreamReader(responseStream);

    string connectionString = ConfigurationSettings.AppSettings.Get("connectionString");
    string folderName = "Inbox/";
    string file = reader.ReadLine();
    while (!string.IsNullOrEmpty(file))
    {

        string fileName = Path.GetFileNameWithoutExtension(file);
        string guid = Guid.NewGuid().ToString();
        string extension = Path.GetExtension(file);
        try
        {
            Stream fileForBlobStorage = reader.BaseStream;
            if (CloudStorageAccount.TryParse(connectionString, out storageAccount))
            {
                CloudBlobClient cloudBlobClient = storageAccount.CreateCloudBlobClient();
                CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("falcon");
                BlobContainerPermissions permissions = new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Blob
                };
                await cloudBlobContainer.SetPermissionsAsync(permissions);

                CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(folderName + fileName + "-" + '[' + guid + ']' + guid + extension.ToString());

                await cloudBlockBlob.UploadFromStreamAsync((Stream  )fileForBlobStorage);
            }
            else
            {
                Console.WriteLine("Connection string not defined.");
            }
        }
        catch (Exception e)
        {
            string message = e.Message;
            Console.WriteLine(message);
        }
        file = reader.ReadLine();
    }
}

标签: c#.netftpazure-blob-storageftpwebrequest

解决方案


您正在请求 FTP 服务器上文件夹的目录列表。同时,您的清单:

  • 逐行(逐个文件)读取列表——以某种方式尝试处理单个行/文件。
  • 然而,您正在尝试将列表(同一流)上传到 blob。

那永远行不通。而且这没有任何意义。

我假设您实际上想要上传文件,而不是列表。

为此,您需要开始从循环中的 FTP 服务器下载各个文件:

FtpWebRequest fileRequest = (FtpWebRequest)WebRequest.Create(ftpPath + file);
fileRequest.Method = WebRequestMethods.Ftp.DownloadFile;
fileRequest.Credentials = new NetworkCredential(ftpUserName, ftpPassword);
FtpWebResponse fileResponse = (FtpWebResponse)fileRequest.GetResponse();
Stream fileStream = fileResponse.GetResponseStream();

await cloudBlockBlob.UploadFromStreamAsync(fileStream);

推荐阅读