0

I can't seem to be able to delete files after a streamreader use, with a

"file can't be accessed because file is in use"

error in C#.

I may miss something but I don't know what, here is the code :

fileEntries = from fullFilename
    in Directory.EnumerateFiles(@"Data\csv\pending")
    select Path.GetFileName(fullFilename);

i = 1;

foreach (string file in fileEntries)
{
    if(i == 1)
    {
        folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\done";

        using (System.IO.FileStream fs = System.IO.File.Create(folder + @"\create-user.csv"))
        {

        }

        using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user.csv", true))
        {
            files.WriteLine(",; prenom; nom; username; pasword; email; question; reponse; GroupID");
        }

        string curfile = @"\create-user-archive.csv";
        if(!(File.Exists(folder + curfile)))
        {
            using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user-archive.csv", true))
            {
                files.WriteLine(",; prenom; nom; username; pasword; email; question; reponse; GroupID");
            }
        }
    }


    folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\pending";
    sb = new StringBuilder();

    filef = new System.IO.StreamReader(folder + @"\create-user-" + i + ".csv");
    line = filef.ReadLine();

    while ((line = filef.ReadLine()) != null)
    {
        sb = new StringBuilder();
        sb.AppendLine(line.Substring(0, line.Length));
        folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\done";
        using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user.csv", true))
        {
            files.WriteLine(",; " + sb.ToString().Split(';')[1] + ";" + sb.ToString().Split(';')[2] + ";" + sb.ToString().Split(';')[1] + "." + sb.ToString().Split(';')[2] + ";" + GenerateToken(6) + ";" + sb.ToString().Split(';')[3] + ";" + "1" + ";" + "1");
        }

        folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\done";
        using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user-archive.csv", true))
        {
            files.WriteLine(",; " + sb.ToString().Split(';')[1] + ";" + sb.ToString().Split(';')[2] + ";" + sb.ToString().Split(';')[1] + "." + sb.ToString().Split(';')[2] + ";" + GenerateToken(6) + ";" + sb.ToString().Split(';')[3] + ";" + "1" + ";" + "1");
        }
    }
    i++;
    sourceFile = System.IO.Path.Combine(@"Data\csv\pending", file);
    File.Delete(sourceFile);
}

shouldn't the file stop being in use after the streamreader is finished? I tried using a function that waits until the file is unlocked to delete the file, but it is infinite, which means there is a never ending process that I must stop, but I don't see which one.

FortyTwo
  • 2,414
  • 3
  • 22
  • 33
raiskader
  • 89
  • 4
  • 16
  • where do you close `filef`? – EpicKip Sep 06 '17 at 08:18
  • "shouldn't the file stop being in use after the streamreader is finished ?" how should the computer know that you have now finished using the file?=! You need to call `Close` on the reader. That is the sign – Mong Zhu Sep 06 '17 at 08:21
  • If you weren't opening and closing the same files multiple times and referring to the same files and folders in a whole variety of ways, it would be easier for you to see what is happening. For example, rather than reusing the very generic `folder` variable for different things, create one called `pendingFolder` to refer to `"Data\csv\pending"` and another called `doneFolder` to refer to `"Data\csv\done"`. Set their value _once_, then actually use those variables instead of hard-coding the same path later. – Rhumborl Sep 06 '17 at 08:26
  • indeed I did not close the streamreader, that was careless of me. Well we all learn from our mistakes – raiskader Sep 06 '17 at 08:27

3 Answers3

3

You need to close filef.

Wrapping the code in a using statement will automatically close the reader

using ( System.IO.StreamReader filef = new System.IO.StreamReader(folder + @"\create-user-" + i + ".csv") {
    ....yourcodehere
}

Alternatively, call filef.Close() when you are done with it (before you delete the file)

hairmot
  • 2,975
  • 1
  • 13
  • 26
0

You have to close the streams you create to dispose the system resources. You can either use the Close method or the using pattern, as the classes implemented IDisposable interface. I would recommend you to the second option.

May have a look to this post: https://stackoverflow.com/a/707339/6244709

Serraniel
  • 296
  • 1
  • 14
0

You will need to call the following;

filef.Close();

This would go before your delete;

  while ((line = filef.ReadLine()) != null)
            {
                sb = new StringBuilder();
                sb.AppendLine(line.Substring(0, line.Length));
                folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\done";
                using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user.csv", true))
                {
                    files.WriteLine(",; " + sb.ToString().Split(';')[1] + ";" + sb.ToString().Split(';')[2] + ";" + sb.ToString().Split(';')[1] + "." + sb.ToString().Split(';')[2] + ";" + GenerateToken(6) + ";" + sb.ToString().Split(';')[3] + ";" + "1" + ";" + "1");
                }

                folder = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + @"\Data\csv\done";
                using (System.IO.StreamWriter files = new System.IO.StreamWriter(folder + @"\create-user-archive.csv", true))
                {
                    files.WriteLine(",; " + sb.ToString().Split(';')[1] + ";" + sb.ToString().Split(';')[2] + ";" + sb.ToString().Split(';')[1] + "." + sb.ToString().Split(';')[2] + ";" + GenerateToken(6) + ";" + sb.ToString().Split(';')[3] + ";" + "1" + ";" + "1");
                }
            }
            i++;
            sourceFile = System.IO.Path.Combine(@"Data\csv\pending", file);
            filef.Close();
            File.Delete(sourceFile);
Tom
  • 12,928
  • 2
  • 15
  • 31