Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

C# WebClient Downloads empty file

I'm working on an app that uses Bing's API to search and download images. Bing's API provides a set of image links and I iterate over them and download each one.

The problem that I'm having is that sometimes the downloaded file size is 0Kb. I assume that happens because WebClient first creates the filename and then tries to write to it. So when it can't write to it for some reason this happens. The problem is that it happens without throwing an exception so my 'Catch' statement can't catch this and delete the file.

public void imageFetcher(string performerName, int maxNumberOfImages, RichTextBox richTextBox)
    {
        string performersDirPath = Environment.CurrentDirectory + @"Performers";
        string performerPath = performersDirPath + performerName + @"";

        if (!Directory.Exists(performersDirPath))
        {
            Directory.CreateDirectory(performersDirPath);
        }

        if (!Directory.Exists(performerPath))
        {
            Directory.CreateDirectory(performerPath);
        }

        // Searching for Images using bing api
        IEnumerable<Bing.ImageResult> bingSearch = bingImageSearch(performerName);

        int i = 0;

            foreach (var result in bingSearch)
            {
                downloadImage(result.MediaUrl, performerPath + performerName + i + ".jpg",richTextBox);
                i++;
                if (i == maxNumberOfImages)
                {
                    break;
                }
            }
    }

The download method:

public void downloadImage(string imgUrl, string saveDestination, RichTextBox richTextBox)
    {
        if (File.Exists(saveDestination))
        {
            richTextBox.ForeColor = System.Drawing.Color.Red;
            richTextBox.AppendText("The File: " + saveDestination + "Already exists");

        }
        else
        {
            try
            {
                using (WebClient client = new WebClient())
                    {

                    client.DownloadFileCompleted += new AsyncCompletedEventHandler(((sender, e) => downloadFinished(sender, e, saveDestination , richTextBox)));
                    Uri imgURI = new Uri(imgUrl, UriKind.Absolute);

                    client.DownloadFileAsync(imgURI, saveDestination);
                    }
            }
            catch (Exception e)
            {
                richTextBox.AppendText("There was an exception downloading the file" + imgUrl);
                richTextBox.AppendText("Deleteing" + saveDestination);
                File.Delete(saveDestination);
                richTextBox.AppendText("File deleted!");

            }

        }

    }

This happens also when I try to wait for the client to finish using:

client.DownloadFileAsync(imgURI, saveDestination);

                        while (client.IsBusy)
                        {

                        }

Can anyone please tell me what I'm doing wrong?

In other simular question the solution was to keep the Webclient instance open until download is finished.. I'm doing this with this loop:

while (client.IsBusy){}

Yet the results are the same.

Update: I resorted to not use webclient, instead I used this code:

try
                        {
                            byte[] lnBuffer;
                            byte[] lnFile;

                            using (BinaryReader lxBR = new BinaryReader(stream))
                            {
                                using (MemoryStream lxMS = new MemoryStream())
                                {
                                    lnBuffer = lxBR.ReadBytes(1024);
                                    while (lnBuffer.Length > 0)
                                    {
                                        lxMS.Write(lnBuffer, 0, lnBuffer.Length);
                                        lnBuffer = lxBR.ReadBytes(1024);
                                    }
                                    lnFile = new byte[(int)lxMS.Length];
                                    lxMS.Position = 0;
                                    lxMS.Read(lnFile, 0, lnFile.Length);
                                }

using (System.IO.FileStream lxFS = new FileStream(saveDestination, FileMode.Create))
                                    {

                                        lxFS.Write(lnFile, 0, lnFile.Length);
                                    }

This solves the problem almost complelty, there are still one or two 0KB files but I assume it's because of network errors.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To see possible exceptions - try changing DownloadFileAsync to just DownloadFile - my problem was "Can not create SSL/TLS secure channel". Hope this will help someone.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...