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

2

I have a class that retrieves data from bank and saves in a D.Reader, and I 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 into a d.table and delete what is being read, in that 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 into the problem ... It writes everything quietly ... At the time of reading, randomly, some files are not closed and throw the exception of System.IO ( question title ) in that line:

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

I've tried using Lock, synchronized, GC dispose to try to isolate the thread / process and I did not succeed. It is worth mentioning that if I execute the 2 methods separately, 1st I execute the program to write closing and then I open to read, it does not throw this exception. And I also did the reading, skipping those that were being used and it is not a cascade (cascade in the sense of "that file forward"), are random files that are still being "used" ... I already used Close and Dispose individually and together in the first method.

Here's the calling method if needed:

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 an idea what it might be?

    
asked by anonymous 24.05.2018 / 17:21

2 answers

1

First, when you have using , do not there is a need to call the Dispose method after the same object.

  

The using statement calls the Dispose method on the object in the correct way and it also causes the object itself to exit the scope as soon as Dispose is called. Within the using block, the object is read-only and can not be modified or reassigned.

Then 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 (it's redundant).

And in relation to your error, I believe that Reinaldo answered correctly, you have StreamWriter that are not being closed in the writing method.

Note, you create a new one and do not end 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 putting 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++;
    }
}

In this way, you guarantee that each loop will be created a new file and it will be "closed" correctly.

    
25.05.2018 / 05:33
3

Your StreamWriters are getting open, use them as a variable / object and after use invoke the sw.Close() method of closing

    
24.05.2018 / 18:01