Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
nanshakov
Студент :)
893 / 326 / 12
Регистрация: 29.01.2011
Сообщений: 1,680
1

WebClient.DownloadFileAsync и потеря данных (скачивание картинок с сервера)

01.07.2014, 02:12. Просмотров 1470. Ответов 8
Метки нет (Все метки)

Сохраняю картинки с сервера этим способом, их от 100 до 300. Скачивается быстро, все хорошо, но некоторые файлы после завершения работы остаются пустыми..от чего это происходит и как с этим бороться ? Видимо они не успевают записаться на диск...т.к. на ssd "битых" меньше, чем на usb hdd. Очень эта проблема настораживает.

Добавлено через 3 часа 13 минут
UrlList.txt - некий файл с построчными прямыми ссылками.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  private void DownloadPhoto()
        {
            string tmp = null;
            string[] Urlparse = System.IO.File.ReadAllLines(pathString + "\\UrlList.txt");
            string[] UrlList = System.IO.File.ReadAllLines(pathString + "\\UrlList.txt");
            if (CountItemsTextEvent != null)
                CountItemsTextEvent(this, new ProcessEventArgs("Всего изображений: " + UrlList.Count()));
            for(int i = 0; i < UrlList.Count(); i++)
            {
                if (ProcessingLTextEvent != null)
                    ProcessingLTextEvent(this, new ProcessEventArgs("Обработанно: " + (i + 1) + " (" + Math.Round(((Convert.ToDouble((i + 1)) / Convert.ToDouble(UrlList.Count())) * 100), 2) + "%)"));
                using (WebClient client = new WebClient())
                {
                    Urlparse[i] = null;
                    //System.Threading.Thread.Sleep(0300);
                    client.DownloadFileAsync(new Uri(UrlList[i]), pathString + UrlList[i].Substring(UrlList[i].LastIndexOf('/')));
                    Urlparse[i] = UrlList[i].Substring(UrlList[i].LastIndexOf('/'));
                    Urlparse[i] = Urlparse[i].TrimStart('/');
                }
            }
            //System.Threading.Thread.Sleep(10000);
            if (StatusTextEvent != null)
                StatusTextEvent(this, new ProcessEventArgs("Статус: Перезагрузка изображений"));
            var dir = new DirectoryInfo(pathString);// папка с файлами 
            foreach (FileInfo file in dir.GetFiles()) // извлекаем все файлы и кидаем их в список 
            {
                FileInfo someFileInfo = new FileInfo(file.FullName);
                long fileByteSize = someFileInfo.Length;
                if (fileByteSize == 0)
                {
                    for (int i = 0; i < Urlparse.Count(); i++)
                    {
                        if (CountItemsTextEvent != null)
                            CountItemsTextEvent(this, new ProcessEventArgs("Всего изображений: " + i));
                        if(file.Name == Urlparse[i])
                        {   using (WebClient client = new WebClient())
                            {
                                int c = 1;
                                tmp = UrlList[i].Substring(UrlList[i].LastIndexOf('/'));
                                tmp = tmp.TrimStart('/');
                                client.DownloadFile(new Uri(UrlList[i]), pathString+"\\img\\"+tmp);
                                if (ProcessingLTextEvent != null)
                                    ProcessingLTextEvent(this, new ProcessEventArgs("Обработанно: " + (c + 1) + " (" + Math.Round(((Convert.ToDouble((c + 1)) / Convert.ToDouble(i)) * 100), 2) + "%)"));
                            }
                        }
                    }
                }
            }
            var dir_ = new DirectoryInfo(pathString+"\\img");
            foreach (FileInfo file in dir.GetFiles())
            {
                if (System.IO.File.Exists(pathString + "\\" + file.Name))
                File.Delete(pathString + "\\" + file.Name);
                File.Move(file.FullName, pathString);
            }
            System.IO.File.Create(pathString + "\\UrlList.txt");
        }
    }
Правда, еслждать неопределенно долго - то и асинхронный метод все загружает...
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.07.2014, 02:12
Ответы с готовыми решениями:

Ссылки для скачивания с помощью WebClient.DownloadFile и WebClient.DownloadFileAsync
Ссылки какие должны быть, для скачивания webClient.DownloadFile и webClient.DownloadFileAsync Не...

WebClient.DownloadFileAsync()
Не определяется размер файла, а, соответственно, и процент загрузки. Вроде по гайду переписал метод...

Не качает файл webClient.DownloadFileAsync
имею вот такой код. string log = File.ReadAllText(@&quot;setting.ini&quot;);///тут путь куда сохранять ...

WebClient.DownloadFileAsync - что такое userToken ?
Пытаюсь использовать асинхронный метод загрузки, т.к. блокирующий сильно замедляет все. Читаю...

WebClient.DownloadFileAsync и выполнение действий в основном потоке после загрузки
Здравствуйте, уважаемые форумчане, поставлена простая задача - скачать ZIP-архив, а после закачки...

8
StudAssistant
Эксперт
34811 / 27003 / 5019
Регистрация: 17.04.2006
Сообщений: 49,622
01.07.2014, 02:12
Закажите контрольную, курсовую, диплом или любую другую студенческую работу здесь.
8
insite2012
Модератор
Эксперт .NET
4890 / 3842 / 1097
Регистрация: 12.10.2013
Сообщений: 11,101
Записей в блоге: 2
01.07.2014, 08:51 2
nanshakov, в строну WebClient.DownloadFileCompleted события не смотрели? В вашем коде я не увидел его применение...
1
nanshakov
Студент :)
893 / 326 / 12
Регистрация: 29.01.2011
Сообщений: 1,680
01.07.2014, 11:03  [ТС] 3
insite2012, нет, сейчас посмотрю, почитаю. Мой код это так, костыли, ищет битые файлы и перезагружает их.. попытаюсь сделать теперь "нормально"

Добавлено через 15 минут
Посмотрел, но не сосем понял, как его применить, там обычно статические урл используются, а я беру из файлв фором, же.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 private void DownloadPhoto()
        {
            string[] UrlList = System.IO.File.ReadAllLines(pathString + "\\UrlList.txt");
            if (CountItemsTextEvent != null)
                CountItemsTextEvent(this, new ProcessEventArgs("Всего изображений: " + UrlList.Count()));
            for(int i = 0; i < UrlList.Count(); i++)
            {
                if (ProcessingLTextEvent != null)
                    ProcessingLTextEvent(this, new ProcessEventArgs("Обработанно: " + (i + 1) + " (" + Math.Round(((Convert.ToDouble((i + 1)) / Convert.ToDouble(UrlList.Count())) * 100), 2) + "%)"));
                using (WebClient client = new WebClient())
                {
                    client.DownloadFileAsync(new Uri(UrlList[i]), pathString + UrlList[i].Substring(UrlList[i].LastIndexOf('/')));
                }
            }
        }
даже если взять пример с ндсм
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
 // Sample call : DownLoadFileInBackground2 ("http://www.contoso.com/logs/January.txt");
    public static void DownLoadFileInBackground2 (string address)
    {
        WebClient client = new WebClient ();
        Uri uri = new Uri(address);
 
        // Specify that the DownloadFileCallback method gets called
        // when the download completes.
        client.DownloadFileCompleted += new AsyncCompletedEventHandler (DownloadFileCallback2);
        // Specify a progress notification handler.
        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressCallback);
        client.DownloadFileAsync (uri, "serverdata.txt");
    }
Я так понимаю, что после завершения
C#
1
client.DownloadFileAsync (uri, "serverdata.txt");
срабатывает событие client.DownloadFileCompleted, которое заново запускает загрузку через DownLoadFileInBackground2().
Мне полного кода не надо, мне бы подсказку куда копать. создать еще 1 ф - цию и передавать туда параметры, т.е. номер i строки ?

Добавлено через 25 минут
Изменил код, по примеру с майкросовт
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        private void DownloadPhoto()
        {
            string[] UrlList = System.IO.File.ReadAllLines(pathString + "\\UrlList.txt");
            if (CountItemsTextEvent != null)
                CountItemsTextEvent(this, new ProcessEventArgs("Всего изображений: " + UrlList.Count()));
            for(int i = 0; i < UrlList.Count(); i++)
            {
                if (ProcessingLTextEvent != null)
                    ProcessingLTextEvent(this, new ProcessEventArgs("Обработанно: " + (i + 1) + " (" + Math.Round(((Convert.ToDouble((i + 1)) / Convert.ToDouble(UrlList.Count())) * 100), 2) + "%)"));
                DownLoadFileInBackground2(UrlList[i]);
                /*using (WebClient client = new WebClient())
                {
                    client.DownloadFileAsync(new Uri(UrlList[i]), pathString + UrlList[i].Substring(UrlList[i].LastIndexOf('/')));
                }*/
            }
        }
        public void DownLoadFileInBackground2(string address)
        {
            WebClient client = new WebClient();
            Uri uri = new Uri(address);
            client.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(DownLoadFileInBackground2);
            client.DownloadFileAsync(uri, pathString + address.Substring(address.LastIndexOf('/')));
        }
    }
Получаем Ни одна перегрузка для "DownLoadFileInBackground2" не соответствует делегированному "System.ComponentModel.AsyncCompletedEventHandler"
Если вместо
C#
1
+= new System.ComponentModel.AsyncCompletedEventHandler(DownLoadFileInBackground2);
DownLoadFileInBackground2 поставить например
C#
1
2
3
4
private void Completed(object sender, AsyncCompletedEventArgs e)
{
  MessageBox.Show("Download completed!");
}
то все работает, что логично. В чем проблема понимаю, нот не знаю как исправить.
0
insite2012
Модератор
Эксперт .NET
4890 / 3842 / 1097
Регистрация: 12.10.2013
Сообщений: 11,101
Записей в блоге: 2
02.07.2014, 14:33 4
nanshakov, попробую сформулировать вашу задачу более точно.
Есть список урлов (уже есть, процесс их получения-отдельная тема). Вы хотите через клиент заходить на каждый урл (в отдельном потоке, чтобы не блокировать интерфейс) и скачивать с каждого файл. Ну и отслеживать прогресс работы процесса скачивания. Все верно?
0
02.07.2014, 14:33
nanshakov
Студент :)
893 / 326 / 12
Регистрация: 29.01.2011
Сообщений: 1,680
02.07.2014, 20:15  [ТС] 5
insite2012, Да, все верно.
0
insite2012
Модератор
Эксперт .NET
4890 / 3842 / 1097
Регистрация: 12.10.2013
Сообщений: 11,101
Записей в блоге: 2
02.07.2014, 20:56 6
Лучший ответ Сообщение было отмечено nanshakov как решение

Решение

nanshakov, вот простенький пример. У меня нет никакого списка урлов (и придумывать как-то не получается), откуда скачивать. Но при доработке должно пойти...
Класс
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;
 
namespace WebLoader
{
    public class FileLoader
    {
        WebClient client = new WebClient();
        EventWaitHandle ready = new AutoResetEvent(false);
        List<string> urlsList;
 
        public FileLoader(List<string> urls)
        {
            urlsList = urls;
            client.DownloadFileCompleted += (s, e) => { ready.Set(); };
            new Thread(Work).Start();
        }
        void Work()
        {
            ready.Set();
 
            for(int i=0; i<urlsList.Count; i++)
            {
                Uri myUri = new Uri(urlsList[i]);
                client.DownloadFileAsync(myUri, string.Format("{0}{1}", Directory.GetCurrentDirectory(), "MyFile" + i + ".txt"));
                ready.WaitOne();
            }
        }
    }
}
Консоль
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace WebLoader
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> urls = new List<string>
            {
                //Тут пишем списoк урлов, из которых надо загружать файлы
            };
            FileLoader loader = new FileLoader(urls);
 
            Console.ReadLine();
        }
    }
}
1
nanshakov
Студент :)
893 / 326 / 12
Регистрация: 29.01.2011
Сообщений: 1,680
05.07.2014, 12:49  [ТС] 7
insite2012, я чуть чуть переделал ваш код, так как с коллекцией list у меня не очень получилось работать, заменил на массив стринг, это не принципиально, но эффект тот же.
Вылетает исключение
Необработанное исключение типа "System.NotSupportedException" в System.dll
Дополнительные сведения: WebClient не поддерживает параллельные операции ввода-вывода.
Класс
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   public class FileLoader
    {
        WebClient client = new WebClient();
        EventWaitHandle ready = new AutoResetEvent(false);
        string[] urlsList;
 
        public FileLoader(string[] urls)
        {
            urlsList = urls;
            client.DownloadFileCompleted += (s, e) => { ready.Set(); };
            new Thread(Work).Start();
        }
        void Work()
        {
            ready.Set();
            for (int i = 0; i < urlsList.Count(); i++)
            {
                Uri myUri = new Uri(urlsList[i]);
                client.DownloadFileAsync(myUri, string.Format("{0}{1}", Directory.GetCurrentDirectory(), "MyFile" + i + ".txt"));
                ready.WaitOne();
            }
        }
    }
Инициализируем
C#
1
2
3
4
5
6
7
 private void DownloadPhoto()
        {
            string[] UrlList = System.IO.File.ReadAllLines(pathString + "\\UrlList.txt");
            if (CountItemsTextEvent != null)
                CountItemsTextEvent(this, new ProcessEventArgs("Всего изображений: " + UrlList.Count()));
            FileLoader loader = new FileLoader(UrlList);
        }
0
nanshakov
Студент :)
893 / 326 / 12
Регистрация: 29.01.2011
Сообщений: 1,680
05.07.2014, 12:59  [ТС] 8
вот список урлов..вдруг нужно.
0
Вложения
Тип файла: txt UrlList.txt (162 байт, 8 просмотров)
insite2012
Модератор
Эксперт .NET
4890 / 3842 / 1097
Регистрация: 12.10.2013
Сообщений: 11,101
Записей в блоге: 2
05.07.2014, 20:20 9
nanshakov, ок, попробую накидать работающий пример.
0
05.07.2014, 20:20
StackOverflow
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.07.2014, 20:20

WebClient.DownloadFileAsync() - скачивание по непрямой ссылке
Привет всем, помогите решить проблему. Использую webClient.DownloadFileAsync для скачивания файлов....

Дозакачка файла, если не докачался WebClient, DownloadFileAsync
Здравствуйте! Проблема в том, что при скачивании файла modpack.zip, он у меня скачивается не...

Асинхронная загрузка файлов методом WebClient.DownloadFileAsync
Вопрос адресуется в первую очередь профессионалам. При разработке приложения возникла...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru