"The process cannot access the file because it is being used by another process"

Asked

Viewed 3,609 times

0

I have a class that retrieves database data and stores it in a D.Reader, and write each record in a text file, in this method:

 public void Escreve_Arquivos_Txt()
    {

        string folder = Program.caminhoAplicacao + @"\Serializer"; //Cria Pasta para Serialização           
        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }
        int ContaArquivo = 0;
        int count = dataReader.FieldCount;
        using (file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + "Ser.txt"))
        {                
            while (this.dataReader.Read()) 
            {
                file.AutoFlush = true; // Limpa o buffer pra forçar a escrita
                for (int i = 0; i < count; i++)
                {
                    file.WriteLine(this.dataReader.GetValue(i));
                }
                ContaArquivo++;
                file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + @"Ser.txt");
            }                                
        }
        file.Dispose();
    }

And I have another method to read these files, insert in a d.table and delete what is being read, in this other method:

private DataTable Preenche_Datatable(DataTable dataTable, int ContaArquivo, string diretorio, int quant_coluna)
    {
        do
        {
            int auxiliacount = quant_coluna - 1;
            int colunaIndex = 0;                
            string[] totaldelinhas = File.ReadAllLines(diretorio + ContaArquivo + "Ser.txt");
            DataRow dr = dataTable.NewRow();
            foreach (string contalinhas in totaldelinhas)
            {
                dr[colunaIndex] = contalinhas;
                if (colunaIndex == auxiliacount)
                {
                    dataTable.Rows.Add(dr);
                    dr = dataTable.NewRow();
                    colunaIndex = 0;
                }
                else
                {
                    colunaIndex++;
                }
            }
            File.Delete(diretorio + ContaArquivo + "Ser.txt");
            ContaArquivo++;
        }
        while (File.Exists(diretorio + ContaArquivo + "Ser.txt"));
        return dataTable;
    }

Let’s get to the problem... He writes everything quietly... At the time of reading, randomly, some files are not closed and release the exception of System.IO(title of the question) along those lines:

string[] totaldelinhas = File.ReadAllLines(diretorio + ContaArquivo + "Ser.txt");

I have tried using Lock, Synchronized, GC Device to try to isolate the thread/process and was unsuccessful. It is worth mentioning that if I execute the 2 methods separately, 1° I run the program to write closing and then open to read, he does not make this exception. And I also ran the reading, skipping the ones that were being used and is not a cascade (cascade in the sense of "that file forward"), are random files that continue to be "used"... I’ve used individual Close and Dispose together in the first method.

Here’s the call method if necessary:

public DataTable Nova_Serializacao(DataTable dataTable)
    {
        Escreve_Arquivos_Txt();
        string dir = Program.caminhoAplicacao + @"\Serializer\"; 
        int count = dataReader.FieldCount;
        Recupera_Colunas(dataReader, count);
        int ContaArquivo = 0;            
        Preenche_Datatable(dataTable, ContaArquivo, dir, count);
        return dataTable;
    }

Does anyone have any idea what it might be?

2 answers

1

Their StreamWriters are opening, uses them as variable/object and after use invokes the closing method sw.Close()

  • I already used Dispose and close in the first method that uses Sw .. I’ve used individual Close and Dispose together in the first method. And in case it works for one and wouldn’t work for the other?

  • Also, I’m using them inside a Using that there is an idisposable after it exits the block, and I reinforced giving a Dispose after it leaves the block, and as I said, I already put the close.

  • correction. Indeed it was that, the friend of the other answer, actually signaled me where it was, that I did not have the same perspective.

1


First, when you have the using, no need to call the method Dispose followed by the same object.

The instruction using calls the Dispose method on the object in the right way and it also causes the object itself to exit the scope as soon as Dispose is called. Inside the using block, the object is read-only and cannot be modified or reassigned.

So in your code:

using (file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + "Ser.txt"))
{
    while (this.dataReader.Read())
    {
        file.AutoFlush = true; // Limpa o buffer pra forçar a escrita
        for (int i = 0; i < count; i++)
        {
file.WriteLine(this.dataReader.GetValue(i));
        }
        ContaArquivo++;
        file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + @"Ser.txt");
    }
}
file.Dispose(); //Esta chamada é desnecessária.

This call file.Dispose(); can be removed (is reducer).

And regarding your mistake, I believe Reinaldo answered correctly, you own StreamWriter that are not being closed in the writing method.

Note, you create a new one and do not finish the old one:

using (file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + "Ser.txt"))
{
    while (this.dataReader.Read())
    {
        file.AutoFlush = true; // Limpa o buffer pra forçar a escrita
        for (int i = 0; i < count; i++)
        {
file.WriteLine(this.dataReader.GetValue(i));
        }
        ContaArquivo++;

        //Nesta linha você cria uma nova instância do StreamWriter mas o anterior (o do loop atrás) não é fechado.
        file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + @"Ser.txt");
    }
}

Try to put the using inside the loop, for example:

while (this.dataReader.Read())
{
    using (var file = new StreamWriter(Program.caminhoAplicacao + @"\Serializer\" + ContaArquivo + "Ser.txt"))
    {
        file.AutoFlush = true; // Limpa o buffer pra forçar a escrita
        for (int i = 0; i < count; i++)
        {
            file.WriteLine(this.dataReader.GetValue(i));
        }
        ContaArquivo++;
    }
}

This way, you ensure that each loop will be created a new file and it will be "closed" correctly.

  • I tested here, and in fact that was it. About Disposis and using, it was a desperate intentional redundancy.

  • Most grateful

Browser other questions tagged

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