D
D
Dmitry Afonchenko2015-12-19 21:03:04
C++ / C#
Dmitry Afonchenko, 2015-12-19 21:03:04

How to properly implement asynchronous copying of C# files?

Good evening, comrades! I had this question:
There is a code for a button that asynchronously copies photos from one folder to another, after checking them by the date they were taken. I took the example from MSDN as a basis, but for some reason after copying the files, they do not open. When copying, I use the CopyToAsync method. Thanks in advance to everyone who will respond and at least point the way in the direction of which you need to dig.
Here is the button code:

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);
                                }
                            }
                        }
                    }
                }
            }
        }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Afonchenko, 2015-12-19
@Indermove

Came to a decision. Maybe (maybe), in these lines

BitmapDecoder decoder = BitmapDecoder.Create(detectDate, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
InPlaceBitmapMetadataWriter pngInplace = decoder.Frames[0].CreateInPlaceBitmapMetadataWriter();

there is interference in the stream, which violates the structure of the file. To fix this, you need to create a new file stream, the resources of which will be released immediately before copying.
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);
                                    }
                                }
                                
                            }
                        }
                    }
                }
            }
        }

P
Peter, 2015-12-20
@petermzg

It seems to me that you open a file, first you read the part of the file, which is the header, and then you copy the rest of the stream into another file. Are the original and copied file sizes different?
And why don't you want to copy the file like this:

public async Task CopyFileAsync(string sourcePath, string destinationPath)
{
  using (Stream source = File.Open(sourcePath))
  {
    using(Stream destination = File.Create(destinationPath))
    {
      await source.CopyToAsync(destination);
    }
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question