How to move files read by StreamReader in C #?

5

I'm trying to move some files. For each file containing the word "TEST" in your body, my application indicates that it is an item found. The goal is to move them to another directory. Here is 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 you can see, the stream method inside 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 system or unauthorized volume access directory. The test was also performed 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 path.

    
asked by anonymous 19.10.2014 / 02:27

1 answer

4

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 heap organization by doing this.

Never catch an exception that you do not know well for. And never capture more than you should. Mostly do not capture Exception . See this # to learn about exceptions. You follow all the links in the response and the links contained in the others you follow. Is 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 do not worry, C # is pretty much the same, and most of the links will lead to specific answers about C #.

You're making two classic mistakes. It tries to have the GC collect garbage because its application is leaking memory. Repair the leak. Collecting junk will not solve your problem. You're trying to "hide" a mistake that's going to happen. try catch was not meant to pretend that no error happened, it was meant to catch errors that you know how to handle. If you do not know how to resolve it, let the other part of the application handle the error, even break the application.

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

There are a few more 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 are looking for, mark it, close the file, and move. I could not test it yet but more or less would be this:

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 placed GitHub for future reference.

If you still feel that you should catch an exception to put the message in lblvirus.Text but capture in the right location and only the specific exception, at most IOException , but preferably a more specific one.

    
19.10.2014 / 03:39