How to move files read by Streamreader in C#?

Asked

Viewed 976 times

7

I am trying to move some files. For each file containing the word "TEST" in its body, my application indicates being a found item. The goal is to move them to another directory. Follow the code below:

string[] Lista = new string[] { "TESTE"};

string dir = @"C:\ORIGEM";
string dir2 = @"C:\DESTINO";

private void btnQuarentena_Click(object sender, EventArgs e)
{
   List<string> busca= Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories).ToList();                  
   foreach (string item in busca)
   {                                              
     StreamReader stream = new StreamReader(item);
     string ler = stream.ReadToEnd();
            foreach (string st in Lista)
            {
              if (Regex.IsMatch(ler, st))
              {
                try
                        {                            
                            stream.Close();
                            stream = null;
                            GC.Collect();
                            File.SetAttributes(dir, FileAttributes.Normal);
                            File.Move(item, dir2);

                        }
                        catch (Exception ex)
                        {
                            lblvirus.Text = "Alguns arquivos não puderam ser movidos! " + ex;
                        }
              }                             
            }
   }
}

As it turns out, the method stream inside of my Try catch block has been disabled, so there are no process errors. Visual Studio returns me an unauthorized access error, and it is not a directory to access the system volume or unauthorized. The test was performed also with removable storage devices, and the same error occurs, being:

An unhandled Exception of type 'System.Unauthorizedaccessexception' occurred in mscorlib.dll Additional information: Access denied to the path.

1 answer

5


There are several errors there. First I think you should read it in a simpler way. But I will follow your line.

Never use GC.Collect unless you know very well what you are doing and have mastery of all the implications. You are destroying the organization of heap doing this.

Never capture an exception you don’t know well for that. And never capture more than you should. Mainly don’t capture the Exception. Look at this another answer to learn about exceptions. Follow all the response links and the links contained in the others you follow. It’s important. I know, it’s a lot of text to read, but it’s critical that you understand how to use exception. Some texts I talk about Java but don’t worry, in C# is very similar, and most of the links will lead to specific answers about C#.

You are making two classic mistakes. Try to have GC collect garbage because your application is leaking memory. Fix the leak. Collecting trash will not solve your problem. You are trying to "hide" an error that will happen. try catch was not made to pretend that no mistake happened, it was made to capture errors that you know how to treat. If you don’t know how to fix it, let the other part of the application handle the error, even break the application.

The dir2 is just one path simple, and the parameter there should be a path complete. You will have to assemble it before passing as argument through the GetFileName() and Path.Combine().

There are a few other things that the solution is not ideal but I will not interfere because it is not the focus of the question.

What you need to do: read the file, find what you’re looking for, mark it, close the file, and move. I couldn’t test yet but more or less would be the following:

string[] Lista = new string[] { "TESTE"};

string dir = @"C:\ORIGEM";
string dir2 = @"C:\DESTINO";

private void btnQuarentena_Click(object sender, EventArgs e) {
    List<string> busca= Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories).ToList();
    foreach (string item in busca) {
        var achou = false;
        //abre o arquivo "garantindo" seu fechamento no final do escopo
        using (var stream = new StreamReader(item)) {
            var arquivo = stream.ReadToEnd();
            foreach (var texto in Lista) {
                if (Regex.IsMatch(arquivo, texto)) {
                    achou = true;
                    break; //se achou não precisa mais continuar procurando
                }
            }
        }
        if (achou) {
            //não se esqueça que o using "garantiu" o fechamento do arquivo
            File.Move(item, Path.Combine(dir2, Path.GetFileName(item)));
        }
    }
}

I put in the Github for future reference.

If you still think you should capture an exception to put the message on lblvirus.Text but capture at the right location and only the specific exception, at most the IOException but preferably a more specific.

  • Thanks, but unfortunately it didn’t work. Same error occurred.

  • Have you tried moving the file purely and simply without doing anything with it? It seems that your problem is of permission on the operating system.

  • No, but I can erase it. If there are other files in the source directory that do not contain the word "TEST" inside its body, these are ignored, being deleted only those that contain it. By this logic, maybe it is not a permission problem. I will take the test, it does not cost to try.

  • Tried to replace by FileInfo.MoveTo()?

  • Now that I realize dir2 is just one path simple, and the parameter there should be a path complete. I’m guessing you’ll have to ride it before you pass as argument.

  • It worked. Really what was missing was matching the directory in the way you edited it. Thank you very much, it has helped me a lot so far @bigown!

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.