2
\$\begingroup\$

I have a .tgz file that I need to download given a url inside a Testing folder and then decompress it. I am able to download the .tgz file successfully from the url and also able to successfully decompress it without any issues. My .tgz file will be approx 100 MB max. I am using SharpZipLib library here to decompress.

There are two parts to this:

  • Download .tgz file from a url in a particular folder.
  • If file is downloaded successfully then only decompress .tgz file in that same folder othewise not.

Below is my code:

private void DownloadTGZFile(string url, string fileToDownload)
{
    using (var client = new WebClient())
    {
        client.DownloadFile(url + fileToDownload, "Testing/configs.tgz");
    }
    Stream inStream = File.OpenRead("Testing/configs.tgz");
    Stream gzipStream = new GZipInputStream(inStream);

    TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
    tarArchive.ExtractContents("Testing/");
    tarArchive.Close();

    gzipStream.Close();
    inStream.Close();
}

Question:

I wanted to check on below things:

  • Is using WebClient efficient here? If not, then what can I use to download the file efficiently for me considering file size is 100 MB max?
  • Also can I add a timeout here so that if I am not able to download the file in that time period, then it just times out. But it should retry for 3 times (or with some retry policy) and skip it if not able to by logging an error for the last try.
  • And if it is able to download the .tgz file successfully then decompress it in the same folder.

I am a newbie who started working with C# so still confuse on usage of WebClient and not sure if it is the right way to do it also. And this will be a production code so wanted to see what's the best way to re-write this whole code if there is any.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Have you considered to use HttpClient instead of WebClient? (Or RestSharp or Flurl) \$\endgroup\$ Jul 17, 2020 at 6:27
  • 1
    \$\begingroup\$ I am ok using HttpClient instead of WebClient. Can you provide an example on how my code should be with that and also any improvements considering it's a production code? @PeterCsala \$\endgroup\$
    – dragons
    Jul 17, 2020 at 13:37

2 Answers 2

2
\$\begingroup\$

DownloadTGZFile does two things, which is one thing too many.

  • It does what it name says it does (download a .TGZ file),
  • but it also unpacks the TGZ file, and that is not in the method's name.

Unpacking the file should be a different method. You should then have a new method that calls both methods.


Also, please follow the Microsoft guidelines:

The PascalCasing convention, used for all identifiers except parameter names, capitalizes the first character of each word (including acronyms over two letters in length), as shown in the following examples:

PropertyDescriptor HtmlTag

A special case is made for two-letter acronyms in which both letters are capitalized, as shown in the following identifier:

IOStream

Thus the method name should be DownloadTgzFile.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for your suggestion. Can you provide an example on how my code should look like considering it is a production code. It will help me understand better also. \$\endgroup\$
    – dragons
    Jul 17, 2020 at 13:29
1
\$\begingroup\$

I would personally not write the archive to disk unless it's extremely huge (we're talking gigabytes here, and not "it might be gigabytes", but is gigabytes).

Open a stream to the download response content and pass it to your gzip/tar decompressor streams, and then extract the files as they come.

And of course, use better names, that function should be called ExtractTgzFile and take an Uri parameter to download (if you use the modern CodeAnalysis package, you'll get a warning for this specifically).

And after that's done, you should rewrite it as an async function, because right now you're wasting time on your caller thread waiting for a file to download, which is unacceptable.

\$\endgroup\$
4
  • \$\begingroup\$ My archive file will be 100 MB max. Do you think you can provide an example on how to do this right way? It will help me understand better as I am pretty new in C#. \$\endgroup\$
    – dragons
    Jul 17, 2020 at 16:21
  • \$\begingroup\$ You just await a HttpClient.GetAsync call, then call the Content property to get the HttpContent instance, then await ReadAsStreamAsync on it to get the stream. Once you have your stream, the rest of the code is the same as what you wrote, pass it to your gzip & tgz stream readers and extract. \$\endgroup\$
    – Blindy
    Jul 17, 2020 at 16:30
  • \$\begingroup\$ Do you think you can provide an example on how to do this? I am still confuse on how to use HttpClient here. Any help will be appreciated. \$\endgroup\$
    – dragons
    Jul 17, 2020 at 17:25
  • \$\begingroup\$ What's confusing? What did you write and what doesn't work? \$\endgroup\$
    – Blindy
    Jul 17, 2020 at 17:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.