-1

So I am currently trying to figure out how I can download a file and then read it right after I download it.

My code downloads it, however when I try to use File.ReadAllText it does not allow me to read it as it says that it is being used by another process (FULL ERROR: "The process cannot access the file 'C:......\netcoreapp3.1\ver.txt' because it is being used by another process.')

I do not know exactly why this is being thrown and I would love to know why and how I can fix it. Thank you for your answers...

Code:

Download Method:

WebClient Client;
public void download(string url, string to)
{
   Uri ur = new Uri(url);
   File.Delete(to);
   addAction("\nDownloading: " + url);
   createFile(to.Substring(0, to.IndexOf(".")), "", to.Substring(to.IndexOf(".") + 1));
   Client = new WebClient();
   Client.DownloadProgressChanged += OnDownloadProgressChanged;
   Client.DownloadFileCompleted += OnDownloadFileCompleted;
   Client.DownloadFileAsync(ur, @"" + to);   


}

Create File Method:

        public void createFile(string name, string content, string type)
        {
            if (!(type == "") && File.Exists(name))
            {
                Console.WriteLine("This file already exists. Delete the file if you want to make a new one.");
                return;
            }
            if (type == "" && Directory.Exists(name))
            {
                Console.WriteLine("This directory already exists. Delete the directory if you want to make a new one.");
                return;
            }
            if (type.Equals(""))
            {
                //make a folder
                Directory.CreateDirectory(name);
                Console.WriteLine("Created the directory: " + name + "!");
            }
            else
            { 
                //make a file.
                using (FileStream fs = File.Create(@"" + name + "." + type))
                {
                    byte[] title = new UTF8Encoding(true).GetBytes(content);
                    fs.Write(title);
                    fs.Close();

                }
            }
        }





Run the download method and trying to access the file and read it:

download("somewebsite with a txt file", "ver.txt");
String ver = File.ReadAllText("Config/Other/ver.txt");
String curver = File.ReadAllText("ver.txt"); //error is here
File.Delete("ver.txt");
  • 1
    Try either awaiting `Client.DownloadFileAsync()` or use `Client.DownloadFile()` instead. It's probably trying to read the file before it's fully downloaded. – Jesse Jan 30 '20 at 03:38
  • fwiw, checking File.Exists() is not good. The file system is _volatile_, meaning you can have a file created or deleted by the user, another thread, or another program, in the short time between when you check .Exists() and when you try to create the file. It can also fail unexpectedly for things like permissions issues, hard links, shared drives, and more. Much better to just put a naive command to create the file inside a try/catch. – Joel Coehoorn Jan 30 '20 at 03:59
  • Also, I see this pattern several times to begin string concatentation: `@"" +`. Whatever you think that accomplishes isn't actually happening. – Joel Coehoorn Jan 30 '20 at 04:00
  • Check if the file locked? The IO Exception is hiding the real problem, see: https://stackoverflow.com/a/11060322/495455 – Jeremy Thompson Jan 30 '20 at 04:05

1 Answers1

0

You are attempting to Read the file before the download has been completed. You can ensure the download is completed by using the OnFileDownloaded Event. For example,

WebClient Client;
public async Task<bool> download(string url, string to)
{
    TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
    Uri ur = new Uri(url);
    File.Delete(to);
    addAction("\nDownloading: " + url);
    createFile(to.Substring(0, to.IndexOf(".")), "", to.Substring(to.IndexOf(".") + 1));
    Client = new WebClient();
    Client.DownloadProgressChanged += OnDownloadProgressChanged;
    Client.DownloadFileCompleted += (d,e)=>{ tcs.SetResult(true);};

    Client.DownloadFileAsync(ur, @"" + to);   

    return await tcs.Task;
}

Now you could use the method as

await download(url,filePath);
String curver = File.ReadAllText(filePath);
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51