[Solved] How can I get the file type of a download?


Put aside background transfer APIs, I think the first question actually you should know is “how to get the file extension from a download Uri”.

For this,we need to consider several scenarios about the “Uri”.

  • The download Uri does have a file extension followed, for example:
    https://code.msdn.microsoft.com/windowsapps/Background-File-Downloader-a9946bc9/file/145559/1/BackgroundDownloader.zip. In this case, we can use Path.GetExtension method that can get the file extension directly.

  • The download Uri has a file extension but also query parameters followed, for example: https://i.stack.imgur.com/7e3M5.jpg?s=328&g=1. In this case, after getting the extension by Path.GetExtension, we need to get the actual extension by getting a sub string or other expressions.

  • The download Uri doesn’t contain a file
    extension. For example,
    https://channel9.msdn.com/Events/Build/2017/T6056/captions?f=webvtt&l=en.
    In this case, commonly we may get the MIME type from the content type
    of http response content header, and then mapping the corresponding
    file extension.

Here is a very simple demo I tested on my side for getting the file extensions of the above Uri:

private async void btnuri_Click(object sender, RoutedEventArgs e)
{
    string ext;
    ext = await GetFileExtention("https://i.stack.imgur.com/7e3M5.jpg?s=328&g=1");
    System.Diagnostics.Debug.WriteLine(ext);
    ext = await GetFileExtention("https://channel9.msdn.com/Events/Build/2017/T6056/captions?f=webvtt&l=en");
    System.Diagnostics.Debug.WriteLine(ext);
    ext = await GetFileExtention("https://code.msdn.microsoft.com/windowsapps/Background-File-Downloader-a9946bc9/file/145559/1/BackgroundDownloader.zip");
    System.Diagnostics.Debug.WriteLine(ext); 
}

public async Task<String> GetFileExtention(string url)
{
    string ext = "";
    try
    {
        if (Path.HasExtension(url))
        {
            ext = Path.GetExtension(url);
            ext = ext.Contains('?') || ext.Contains('=') ? ext.Substring(0, ext.LastIndexOf("?")) : ext;
        }
        else
        {
            HttpClient client = new HttpClient();
            HttpResponseMessage response = await client.GetAsync(new Uri(url));
            IHttpContent res = response.Content;
            string ContentType = res.Headers["Content-Type"];
            string MimeType = ContentType.Substring(0, ContentType.LastIndexOf(";"));
            switch (MimeType)
            {
                case "text/plain":
                    ext = ".txt"; break;
                case "text/vtt":
                    ext = ".vtt"; break;      
                case "text/html":
                    ext = "html"; break;
                default:
                    ext = ".unknown"; break;
            }
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.ToString());
    }
    return ext;
}

And something we need to pay attention about the demo:

  • If you are using background transfer, you need to get the Content-Type header from the Windows.​Networking.​Background​Transfer.Response​Information object, not the IHttpContent. For example:

    private async Task HandleDownloadAsync(DownloadOperation download, bool start)
    {
      ... 
      ResponseInformation response = download.GetResponseInformation();
      var contenttype = response.Headers["Content-Type"]; 
    }
    
  • We list three scenarios about download Uri, but we are not sure if you have other scenarios that you should have other ways to deal with them.

  • The file extension results are not guaranteed since the Content-Type and the file suffix are provided by the server.
  • We don’t list all the MIME type mapping, the above just for simple testing. For more details and more MIME type mappings you can reference this thread and this package.

4

solved How can I get the file type of a download?