Не удается скопировать файл (используя источник Stream) и надежно получить его размер после операции

У меня проблема, из-за которой я читаю файл из каталога на ftp-сервер, и вызов для копирования данных возвращается до того, как данные будут записаны, что заставляет мой вызывающий код думать, что файл пуст, когда на самом деле , данные в конечном итоге записываются с правильными данными. Это странно. Это похоже на то, что копирование происходит за кулисами, но мой код не контролирует статус. Мне абсолютно необходимо убедиться, что данные были записаны, прежде чем я удалю исходный файл (иначе мы можем потерять важные данные).

Вот мой рассматриваемый код. Примечание. Я использую System.Net.FtpClient для подключения к ftp-серверу. Его метод OpenWrite возвращает объект Stream. Кроме того, аргумент Transport, который вы видите в этой функции, — это просто объект с данными конфигурации (исходный/целевой каталог/сервер для подключения, учетные данные, типы файлов для перемещения и т. д. и т. д.). Показывать этот объект было бы излишним. Проблема в этом коде:

public static void MoveFromDirectoryToFTP(Transport transport)
    {

        using (FtpClient destinationServer = new FtpClient())
        {
            destinationServer.Host = transport.Destination.Host;
            destinationServer.Credentials = new NetworkCredential(transport.Destination.UserName, transport.Destination.Password);
            destinationServer.Connect();

            foreach (var file in Directory.EnumerateFiles(transport.Host, transport.FilePattern))
            {
                try
                {
                    if (!File.Exists(file))
                    {
                        continue;
                    }

                    using (FileStream sourceStream = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
                    {
                        if (sourceStream.Length == 0) continue;

                        using (Stream destinationStream = destinationServer.OpenWrite(Path.GetFileName(file), FtpDataType.Binary))
                        {
                            sourceStream.CopyTo(destinationStream, (int)sourceStream.Length);
                        }
                    }
                    //this is returning zero, but a minute later i look at the server and the data is there
                    Debug.WriteLine("size after copy: " + destinationServer.GetFileSize(Path.GetFileName(file)));

                    if (destinationServer.GetFileSize(Path.GetFileName(file)) > 0)
                    {
                        File.Delete(file);   
                    }
                }
                catch (Exception e)
                {
                    Helper.LogErrorToDisk(e.Message + " when processing file " + file, e.Source, e.StackTrace);
                }
            }
        }
    }

Что я делаю не так, и что я могу сделать, чтобы добиться надежной копии файлов между каталогами и ftp-серверами и наоборот.

** РЕДАКТИРОВАТЬ: я только что понял, что этот метод GetFileSize возвращает -1 в моем методе. Я понятия не имею, почему, кроме того, что, возможно, он получает какой-то странный ответ от ftp-сервера, когда он пытается получить размер (который, я уверен, отправляет команду «SIZE»). Интересно, может ли это быть конфигурация сервера? Можно ли настроить ftp-серверы, чтобы они не разрешали извлечение размера файла? **


person inspectorGadget    schedule 28.03.2016    source источник


Ответы (1)


Убедитесь, что размер целевого файла равен размеру исходного файла, затем удалите.

псевдокод..

while destination file size not equal to source file size
  sleep (1000ms)
end while

delete destination file
person Eminem    schedule 28.03.2016