Forum Cross Platform with Xamarin
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

how to download a file from URL in xamarin cross platform project using PCL Support

chiranjibidhalchiranjibidhal USMember

I am new to Xamarin. Facing a lot of difficulties due to only a fraction of .Net assemblies are available for PCL.

I need to download a .db file by hitting a URL which is required to save in local drive. As the project is in PCL So this is not allowing me to use System.IO.File in my project, so making me unable to do the file operations available in .Net class library.

Ex: Suppose I am hitting the URL "http://123.com/register.db" and this returns register.db as reponse. I need to save the register.db as it is in my local storage.

My code to hit the URL is as below

    public static async Task LaunchURLForSync(string targetUrl)
    {

        try
        {

            using (HttpClient client = new HttpClient())
            {
                using (HttpResponseMessage response = await client.GetAsync(targetUrl, HttpCompletionOption.ResponseHeadersRead))
                using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync())
                {
                    string fileToWriteTo = Path.GetFileName();

                    using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create)) // This doesn't work with PCL for ex. FIle.Open etc
                    {
                        await streamToReadFrom.CopyToAsync(streamToWriteTo);
                    }
                }
            }  
        }
        catch (Exception ex)
        {
            throw ex;
        }
    } 

Any help will be highly appreciated. Thank you in advance :)

Posts

  • chiranjibidhalchiranjibidhal USMember

    Hello Alessandro Caliaro,

    Thank you very much for the reply. As I am new to Xamarin, I don't have much idea how the Download Manager works. It will be a great help if you can elaborate it a bit or may be a sample code chunk to understand.

  • chiranjibidhalchiranjibidhal USMember

    Thank you for the suggestion. but it seems the download manager can not be used for my problem.
    Need to get some other solution. :)

  • DaveHuntDaveHunt USMember ✭✭✭✭✭

    We can't help you if we don't know why the download manager wouldn't work for your problem.

  • MommMomm USMember ✭✭✭
    edited July 2016

    @chiranjibidhal, if your problem is using System.IO.File, you could create a DependencyService for IO and use System.IO from each one of the platforms you need (iOS, Android, etc). Using this approach you will be able to use System.IO (File, Path, etc).

    DependencyService: https://developer.xamarin.com/guides/xamarin-forms/dependency-service/introduction/

    Please let me know if it helps.

  • chiranjibidhalchiranjibidhal USMember

    @DaveHunt : I need a synchronous download process, I mean when I request the URL, I will be needing the response and once I get the response I need to proceed with second .db file download which will be a continuation process as my application will be requiring to download numerous .db file.

    As per my understanding the download manager is more of a asynchronous process which takes a broadcast notification on request and the other once the download finished to send notification. and moreover download manager is process which runs on back ground. these are the reasons which forced me to find an alternate solution.

    The above is as per my understanding by going through some forums. please correct me if I have any wrong info or perception about how download manager works.

    If you have any other alternative to download manager, request you to let me know.

    Cheers :)

  • chiranjibidhalchiranjibidhal USMember
    edited July 2016

    @Momm Thanks for the suggestion. :smile: will definitely give a try to this and will let you know.
    Just a initial query : is it only for Xamarin.Forms apps (Mine is Native.Portable app, so will it work in this ?)

  • MommMomm USMember ✭✭✭

    I believe that you need XF to use a DependencyService, but I believe you could create a Shared Project for this very same goal.

  • chiranjibidhalchiranjibidhal USMember
    edited July 2016

    Guys, I got a solution which works perfectly for my requirement. I have taken the help of PCLStorage library package which is available in Nuget. You just need download and install in your project.

    The below code have done the trick for me. Hope it helps someone who is looking for similar kind of solution.

    Note : I am creating a folder structure "Downloads/Db" on the internal storage of my device and there writing the .db file contents which I am getting from URL. I believe this code may also be helpful if you want to save an image as well.

       public static async Task DownloadDb(string Url)
            {
                try
                {
                    Uri url = new Uri(Url);
                    var client = new HttpClient();
    
                    var ext = global::Android.OS.Environment.ExternalStorageDirectory.Path + "/Downloads";
                    IFolder rootfolder = FileSystem.Current.LocalStorage;
                    IFolder appfolder = await rootfolder.CreateFolderAsync(ext, CreationCollisionOption.OpenIfExists);
                    IFolder dbfolder = await appfolder.CreateFolderAsync("Db", CreationCollisionOption.OpenIfExists);
                    IFile file = await dbfolder.CreateFileAsync("register.db", CreationCollisionOption.ReplaceExisting);
                    using (var fileHandler = await file.OpenAsync(FileAccess.ReadAndWrite))
                    {
                        var httpResponse = await client.GetAsync(url);
                        byte[] dataBuffer = await httpResponse.Content.ReadAsByteArrayAsync();
                        await fileHandler.WriteAsync(dataBuffer, 0, dataBuffer.Length);
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            } 
    

    Thank you all for the suggestions. It really help me knowing some new concepts and tricks for working.

    Happy Coding. Cheers :)

  • Rohit_ArnavRohit_Arnav USMember ✭✭

    here is a very good solution

  • vikassharma9782vikassharma9782 Member ✭✭

    Hello,

    I am using Xam.Plugin.DownloadManager plugin for download files but i am unable to download multiple file parallelly on ios plate form . On android plate form it is working fine . Anyone can help me ?

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    @vikassharma9782

    This thread is quite old and may not be relevant for the issue you are having. For troubleshooting a new scenario that is not resolved by the steps earlier in this thread, I would recommend creating a new forum discussion or question. which I see you did here: https://forums.xamarin.com/discussion/127803/unable-to-download-multiple-file-parallelly-xamarin-ios-plate-form#latest

Sign In or Register to comment.