I've been using xamarin for a while and the current project I'm working on will require some mp3 files to be downloaded.
I saw tutorials for downloading a file and downloading an image, but they didn't lead me anywhere and are for iOS.
Given a url www.xyz.com/music.mp3, how do I download the mp3 file and save it?
Simplest way is to use WebClient and if on the UI thread then call method DownloadFileTaskAsync:
button.Click += async delegate
{
var destination = Path.Combine(
System.Environment.GetFolderPath(
System.Environment.SpecialFolder.ApplicationData),
"music.mp3");
await new WebClient().DownloadFileTaskAsync(
new Uri("http://www.xyz.com/music.mp3"),
destination);
};
Xamarin.iOS Docs converted to download bytes
The Xamarin.iOS docs WebClient sample for downloading a file should work just fine after you tweak from downloading a string to downloading bytes (note DownloadDataAsync and DownloadDataCompleted vs String sibling functions).
var webClient = new WebClient();
webClient.DownloadDataCompleted += (s, e) => {
var text = e.Result; // get the downloaded text
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string localFilename = "downloaded.mp3";
string localPath = Path.Combine (documentsPath, localFilename);
File.WriteAllText (localpath, text); // writes to local storage
};
var url = new Uri("http://url.to.some/file.mp3"); // give this an actual URI to an MP3
webClient.DownloadDataAsync(url);
Using HttpClient
If you want to use the newer HttpClient library. Add a reference to System.Net.Http to your Xamarin.Android project and give something like this a shot.
var url = new Uri("http://url.to.some/file.mp3");
var httpClient = new HttpClient ();
httpClient.GetByteArrayAsync(url).ContinueWith(data => {
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
string localFilename = "downloaded.mp3";
string localPath = Path.Combine (documentsPath, localFilename);
File.WriteAllBytes (localPath, data.Result);
});
Related
I have the next url about an image:
https://i.discogs.com/HE17wcv1sG6NDK1WcVyoQjSqUGDZva3SYvm6vXoCMOo/rs:fit/g:sm/q:90/h:600/w:600/czM6Ly9kaXNjb2dz/LWRhdGFiYXNlLWlt/YWdlcy9SLTk2OTY5/NjktMTQ4NDkzNzkw/Ni00MDcyLmpwZWc.jpeg
If I open the url with the navigator and then I press de right button to save this image in my hard disc the name solved by the navigator for this file image is distinct.
How can i get the last name of the file in c#?
If you're set on using WebClient then you can download the data into memory, check for the Content-Disposition header, and then change the filename accordingly. I've added commented out parts that you can use instead of their synchronous counterparts if you're using this method asynchronously.
// private static async Task DownloadImageAsync(string url, string folder)
private static void DownloadImage(string url, string folder)
{
var uri = new Uri(url);
string fileName = Path.GetFileName(uri.AbsolutePath);
WebClient client = new WebClient();
// byte[] fileData = await client.DownloadDataTaskAsync(url);
byte[] fileData = client.DownloadData(url);
string disposition = client.ResponseHeaders.Get("Content-Disposition"); // try to get the disposition
if (!string.IsNullOrEmpty(disposition) // check it has a value
&& ContentDispositionHeaderValue.TryParse(disposition, out var parsedDisposition) // check it can be parsed
&& !string.IsNullOrEmpty(parsedDisposition.FileName)) // check a filename is specified
{
fileName = parsedDisposition.FileName.Trim('"'); // replace the normal filename with the parsed one
}
// await File.WriteAllBytesAsync(Path.Combine(folder, fileName), fileData);
File.WriteAllBytes(Path.Combine(folder, fileName), fileData);
}
Usage: DownloadImage(myurl, #"C:\Users\Me\Desktop");
That said, WebClient is a bit old-fashioned and you should probably use HttpClient for newer developments:
private static async Task DownloadImageAsync(string url, string folder)
{
var uri = new Uri(url);
string fileName = Path.GetFileName(uri.AbsolutePath);
using var response = await _httpClient.GetAsync(url);
response.EnsureSuccessStatusCode();
if (!string.IsNullOrEmpty(response.Content.Headers.ContentDisposition?.FileName))
{
fileName = response.Content.Headers.ContentDisposition.FileName.Trim('"');
}
using var outputFile = File.Create(Path.Combine(folder, fileName));
await response.Content.CopyToAsync(outputFile);
}
Usage: await DownloadImageAsync(myurl, #"C:\Users\Me\Desktop");
Microsoft recommend using a single static instance of HttpClient throughout your application (docs). This does have pitfalls though, so depending on your application, you might want to look into using IHttpClientFactory, which works to solve the issues that come from using a static HttpClient.
Here is my code........
public MediaPlaybackItem GetMediaPlaybackItemFromPath(string path)
{
//StorageFile file = await StorageFile.GetFileFromPathAsync(path);
var source = MediaSource.CreateFromUri(new Uri(path));
return new MediaPlaybackItem(source);
}
If I use this method I cannot play music. But if I try this I can play music.
public async Task<MediaPlaybackItem> GetMediaPlaybackItemFromPathAsync(string path)
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
var source = MediaSource.CreateFromStorageFile(file);
return new MediaPlaybackItem(source);
}
Whats the problem with this? I am using mediaplaybacklist for MediaPlayer.Source . How can I get proper MediaSource using my first method? Help me please.
You could not pass file path parameter to CreateFromUri directly. In general, the Uri parameter is http protocol address such as http://www.testvideo.com/forkvideo/test.mp4. But we could pass the file path with uwp file access uri scheme.
For example:
Media file stored in the installation folder.
ms-appx:///
Local folder.
ms-appdata:///local/
Temporary folder.
ms-appdata:///temp/
For more you could refer this document.
I have a web service, like this example for downloading a zip file from the server. When i open the URL through web browsers,I can download the zip file correctly. The problem is when I try to download the zip file through my desktop application. I use the following code to download:
WebClient webClient = new WebClient();
webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
webClient.DownloadFileAsync(new Uri(#"http://localhost:9000/api/file/GetFile?filename=myPackage.zip"), #"myPackage.zip");
After testing this, I get the myPackage.zip downloaded, but it is empty, 0kb. Any help about this or any other server code + client code example?
You can try to use HttpClient instead. Usually, it is more convenient.
var client = new HttpClient();
var response = await client.GetAsync(#"http://localhost:9000/api/file/GetFile?filename=myPackage.zip");
using (var stream = await response.Content.ReadAsStreamAsync())
{
var fileInfo = new FileInfo("myPackage.zip");
using (var fileStream = fileInfo.OpenWrite())
{
await stream.CopyToAsync(fileStream);
}
}
I'm new to WinForms/C#/VB.NET and all and am trying to put together a simple application which downloads an MP3 file and edits its ID3 tags. This is what I've come up with so far :
Uri link = new System.Uri("URL");
wc.DownloadFileAsync(link, #"C:/music.mp3");
handle.WaitOne();
var file = TagLib.File.Create(#"C:/music.mp3");
file.Tag.Title = "Title";
file.Save();
The top section downloads the file with a pre-defined WebClient, but when I try to open the file in the first line of the second half, I run into this error The process cannot access the file 'C:\music.mp3' because it is being used by another process. which I'm guessing is due to the WebClient.
Any ideas on how to fix this? Thanks.
If using WebClient.DownloadFileAsync you should subscribe to the DownloadFileCompleted event and perform the remainder of your processing from that event.
Quick and dirty:
WebClient wc = new WebClient();
wc.DownloadfileCompleted += completedHandler;
Uri link = new System.Uri("URL");
wc.DownloadFileAsync(link, #"C:/music.mp3");
//handle.WaitOne(); // dunno what this is doing in here.
function completedHandler(Object sender, AsyncCompletedEventArgs e) {
var file = TagLib.File.Create(#"C:/music.mp3");
file.Tag.Title = "Title";
file.Save();
}
We have been requested to go and Download an order file from our customers site via a url.
I want to do something like this.
string remoteUri = "http://www.contoso.com/library/homepage/images/";
string fileName = "ms-banner.gif", myStringWebResource = null;
// Create a new WebClient instance.
using (WebClient myWebClient = new WebClient())
{
myStringWebResource = remoteUri + fileName;
// Download the Web resource and save it into the current filesystem folder.
myWebClient.DownloadFile(myStringWebResource, fileName);
}
But the URL will be variable as we have to specify the Date and Time within the URL we post.
And the File we download will be variable also.
As I'm new to C# I would like some advise as to how to achieve this?
Thanks In Advance
It depends on how the URLs will be generated. Do they follow a pattern? Do you know them in advance?
private void GetVariableFile(string remoteUri, string filename) {
string myStringWebResource = null;
// Create a new WebClient instance.
using (WebClient myWebClient = new WebClient()) {
myStringWebResource = remoteUri + fileName;
// Download the Web resource and save it into the current filesystem folder.
myWebClient.DownloadFile(myStringWebResource, fileName);
//Do stuffs
}
}
You might wanna pass the Uri & the file obtained to a method which will handle the download and the elaboration, or in case you need to return the result, change the return type so that it can return the info you need.