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