Перенос файла из FTP в облако Azure через локальный буфер MemoryStream приводит к «пустому» файлу - PullRequest
1 голос
/ 03 мая 2020

Я пытаюсь написать процедуру, которая будет загружать текстовый файл с FTP-сайта непосредственно в общую папку Azure без предварительной записи файла на диск. Мой план состоит в том, чтобы загрузить данные в MemoryStream, а затем загрузить поток в облачное хранилище. Процедура выполняется, но результирующий файл имеет 0 кб. В качестве теста я также попытался записать данные MemoryStream в локальный файл. Когда я сделал это, полученный файл имел тот же размер, что и исходный файл (8 КБ), но ни одна из данных не была видна при открытии в Блокноте. Может кто-нибудь, пожалуйста, дайте мне знать, где я иду не так?

FtpWebRequest ftpRequest = (FtpWebRequest)FtpWebRequest.Create("ftp://ftp.domain.com:21/ftp/test/FileName.txt");
ftpRequest.Credentials = new NetworkCredential("userName", "password");
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
FtpWebResponse ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
Stream ftpStream = ftpResponse.GetResponseStream();

//Write to a Azure File Share (results in 0 kb file)
using (MemoryStream ms = new MemoryStream())
{
    byte[] byteBuffer = new byte[2048];
    int bytesRead = ftpStream.Read(byteBuffer, 0, 2048);
    while (bytesRead > 0)
    {
        ms.Write(byteBuffer, 0, bytesRead);
        bytesRead = ftpStream.Read(byteBuffer, 0, 2048);
    }

    CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials("accountName", "azureKey"), false);
    CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
    CloudFileShare fileShare = fileClient.GetShareReference(ConfigurationManager.AppSettings.Get("share-name"));
    CloudFileDirectory rootDirectory = fileShare.GetRootDirectoryReference();
    CloudFileDirectory destDir = rootDirectory.GetDirectoryReference("DestnationDirectory");
    var newFile = destDir.GetFileReference("NewDownloadedFile.txt");
    newFile.UploadFromStream(ms);
}

ftpStream.Close();
ftpResponse.Close();

1 Ответ

0 голосов
/ 03 мая 2020

После записи в поток указатель потока находится в конце потока. Поэтому, когда вы передаете поток в CloudFile.UploadFromStream, он читает поток от указателя (который находится в конце) до конца. Следовательно, ничего не написано.

ms.Position = 0;

По аналогичному вопросу см .:
Загрузка из ByteArray / MemoryStream с использованием S SH. NET - Файл создается пустым (с размером 0KB)


Хотя копирование данных в промежуточный буфер / поток является излишним.

Использование WebResponse.GetResponseStream напрямую:

newFile.UploadFromStream(ftpResponse.GetResponseStream());
...