Indermove
@Indermove
C#/.NET back-end разработчик

Как правильно реализовать асинхронное копирование файлов C#?

Добрый вечер, товарищи! У меня возник такой вопрос:
Есть код для кнопки, который занимается тем, что асинхронно копирует фотографии из одной папки в другую, предварительно проверяя их по дате съемки. Взял за основу пример с MSDN, но по какой-то причине после копирования файлов, они не открываются. При копировании использую метод CopyToAsync. Заранее благодарен всем, кто откликнется и хотя бы укажет путь, в сторону которого нужно копать.

Вот код кнопки:
private async void smartButton_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.ShowDialog();

            if (folderBrowserDialog.SelectedPath != "")
            {
                string selectedPath = folderBrowserDialog.SelectedPath;

                folderBrowserDialog.Dispose();

                string[] photos = Directory.GetFiles(selectedPath);

                foreach (ModelGroupItem item in listGroupItem)
                {
                   foreach (string photo in photos)
                    {
                        using (FileStream imageStreamSource = File.Open(photo, FileMode.Open))
                        {
                            BitmapDecoder decoder = BitmapDecoder.Create(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                            InPlaceBitmapMetadataWriter pngInplace = decoder.Frames[0].CreateInPlaceBitmapMetadataWriter();
                            DateTime photoDate = DateTime.Parse(pngInplace.DateTaken); // Дата съемки

                            // Если фотография соответствует условиям, то перекидываем ее в папку
                            if (item.timeTo.TimeOfDay > photoDate.TimeOfDay &
                                item.timeFrom.TimeOfDay < photoDate.TimeOfDay &
                                photoDate.DayOfWeek.ToString() == item.day &
                                photoDate.Month == DateTime.Today.Month)
                            {
                                string StartDirectory = selectedPath;   // Стартовая директория
                                string EndDirectory = item.path;        // Конечная

                                using (FileStream DestinationStream = File.Create(EndDirectory + photo.Substring(photo.LastIndexOf('\\'))))
                                {
                                    await imageStreamSource.CopyToAsync(DestinationStream);
                                }
                            }
                        }
                    }
                }
            }
        }
  • Вопрос задан
  • 1499 просмотров
Решения вопроса 1
Indermove
@Indermove Автор вопроса
C#/.NET back-end разработчик
Дошел, до решения. Возможно (возможно), вот в этих строчках
BitmapDecoder decoder = BitmapDecoder.Create(detectDate, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
InPlaceBitmapMetadataWriter pngInplace = decoder.Frames[0].CreateInPlaceBitmapMetadataWriter();

происходит вмешательство в поток, которое нарушает структуру файла. Чтобы это исправить, нужно создать новый файловый поток, ресурсы которого будем высвобождать непосредственно перед копированием.

private async void smartButton_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
            folderBrowserDialog.ShowDialog();

            if (folderBrowserDialog.SelectedPath != "")
            {
                string selectedPath = folderBrowserDialog.SelectedPath;

                folderBrowserDialog.Dispose();

                string[] photos = Directory.GetFiles(selectedPath);

                foreach (ModelGroupItem item in listGroupItem)
                {
                   foreach (string photo in photos)
                    {
                        using (FileStream detectDate = File.Open(photo, FileMode.Open))
                        {
                            BitmapDecoder decoder = BitmapDecoder.Create(detectDate, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                            InPlaceBitmapMetadataWriter pngInplace = decoder.Frames[0].CreateInPlaceBitmapMetadataWriter();
                            DateTime photoDate = DateTime.Parse(pngInplace.DateTaken); // Дата съемки

                            // Если фотография соответствует условиям, то перекидываем ее в папку
                            if (item.timeTo.TimeOfDay > photoDate.TimeOfDay &
                                item.timeFrom.TimeOfDay < photoDate.TimeOfDay &
                                photoDate.DayOfWeek.ToString() == item.day &
                                photoDate.Month == DateTime.Today.Month)
                            {
                                string StartDirectory = selectedPath;   // Стартовая директория
                                string EndDirectory = item.path;        // Конечная
                                
                                // Освобождаем файл перед копированием
                                detectDate.Dispose();

                                using (FileStream imageStreamSource = File.Open(photo, FileMode.Open))
                                {
                                    using (FileStream DestinationStream = File.Create(EndDirectory + photo.Substring(photo.LastIndexOf('\\'))))
                                    {
                                        await imageStreamSource.CopyToAsync(DestinationStream);
                                    }
                                }
                                
                            }
                        }
                    }
                }
            }
        }
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
petermzg
@petermzg
Самый лучший программист
Мне кажется вы открываете файл, сначала считываете часть файла, что является заголовком, а затем остаток стрима копируете в другой файл. Размер оригинального и скопированного файла разный?
И почему вы не хотите скопировать файл так:
public async Task CopyFileAsync(string sourcePath, string destinationPath)
{
  using (Stream source = File.Open(sourcePath))
  {
    using(Stream destination = File.Create(destinationPath))
    {
      await source.CopyToAsync(destination);
    }
  }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы