Reputation: 538
I am working on xamarin.forms application. I want to download multiple files simultaneously using HttpClient. If there is multiple files then I am getting : System.IO.IOException:Sharing violation on path . Is there anything that has to be improved ? Here is my code for downloading files :
public async Task DownloadFileAsync(string sourceUrl, string filePathWhereToSave, CancellationTokenSource cts)
{
Exception error = null;
bool isCancelled = false;
try
{
if (!downloadingTasks.ContainsKey(sourceUrl))
downloadingTasks.Add(sourceUrl, cts);
var token = cts.Token;
var response = await _client.GetAsync(sourceUrl, HttpCompletionOption.ResponseHeadersRead, token);
response.EnsureSuccessStatusCode();
string fileName = filePathWhereToSave.Substring(filePathWhereToSave.LastIndexOf('/'));
string directory = filePathWhereToSave.Substring(0, filePathWhereToSave.LastIndexOf('/'));
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
Directory.CreateDirectory(directory);
var totalData = response.Content.Headers.ContentLength.GetValueOrDefault(-1L);
var canSendProgress = totalData != -1L;
await Task.Run(async() =>
{
using (var fileStream = OpenStream(filePathWhereToSave))
{
using (var stream = await response.Content.ReadAsStreamAsync())
{
var totalRead = 0L;
var buffer = new byte[bufferSize];
var isMoreDataToRead = true;
do
{
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
if (read == 0)
isMoreDataToRead = false;
else
{
await fileStream.WriteAsync(buffer, 0, read);
totalRead += read;
if (canSendProgress)
{
//var progress = ((totalRead * 1d) / (totalData * 1d) * 100);
MessagingCenter.Send<DownloadFileProgressChangedMessage>(new DownloadFileProgressChangedMessage(sourceUrl, totalRead, totalData, 0), MessageNameConstants.DownloadFileProgressChangedMessage);
}
}
} while (isMoreDataToRead);
}
}
});
}
catch (OperationCanceledException ex)
{
isCancelled = true;
}
catch (Exception e)
{
error = e;
System.Diagnostics.Debug.WriteLine(e.ToString());
}
finally
{
MessagingCenter.Send<DownloadCompletedMessage>(new DownloadCompletedMessage(sourceUrl, filePathWhereToSave, error, isCancelled), MessageNameConstants.DownloadCompletedMessage);
if (downloadingTasks.ContainsKey(sourceUrl))
downloadingTasks.Remove(sourceUrl);
}
}
Upvotes: 0
Views: 988
Reputation: 14475
This may be happening because the file is being locked by the reading stream, so the writing stream can't be created and you get the exception.
To avoid it you could enable read/write access with the class FileStream .
FileStream fileStream = new FileStream(filePathWhereToSave,
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.None);
Or use StreamWriter
using (var writer = new StreamWriter(filePathWhereToSave))
{
// do work here.
}
BTW , what is OpenStream
? I can't find it in any assembly, is it included in a third-party library ?
Refer to
https://stackoverflow.com/a/23779697/8187800
https://stackoverflow.com/a/11541330/8187800
Upvotes: 0