处理文件时内存使用量正在增长

时间:2016-09-12 18:17:58

标签: c# xml

我正在开发一个读取xml文件夹的应用程序,每个文件都要进行一些检查并根据某些条件复制到新文件夹。

但是当它到达foreach循环时,内存使用量会持续增长,而且我认为不会发生这种情况,因为变量在每次迭代时都不会增加,只会被覆盖。

这是我的代码:

using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;

namespace XMLOrganizer
{
    public partial class Form1 : Form
    {

        string selectedFolder;

        public Form1()
        {
            InitializeComponent();
            comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
            comboBox1.SelectedIndex = 0;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            selectedFolder = folderBrowserDialog1.SelectedPath;
            organizeBtn.Enabled = true;
        }

        private void organizeBtn_Click(object sender, EventArgs e)
        {

            if (comboBox1.SelectedIndex == -1)
            {
                MessageBox.Show("Selecione o tipo de nota", "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Exclamation,
                    MessageBoxDefaultButton.Button1);
                return;
            }

            if (comboBox1.SelectedIndex != 2)
            {
                OrganizeXml(label2, selectedFolder, comboBox1);
            }

            //ORGANIZAR LOTES
            else
            {
                string folder = selectedFolder;
                label2.Text = "Arquivos sendo processados, aguarde...";
                label2.Refresh();

                string[] files = Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories);

                int atualFile = 1, totalXML = files.Length;

                foreach (string file in files)
                {
                    XmlDocument xmlDocument = new XmlDocument();
                    xmlDocument.Load(file);
                    XmlNodeList enviNFe = xmlDocument.GetElementsByTagName("enviNFe");
                    string versao = ((XmlElement)enviNFe[0]).Attributes["versao"].Value;
                    XmlNodeList NFe = ((XmlElement)enviNFe[0]).GetElementsByTagName("NFe");

                    Directory.CreateDirectory(selectedFolder + @"\NOTAS");

                    label2.Text = "Processando arquivo " + atualFile + " de " + totalXML;

                    string notaXML;
                    foreach (XmlElement nota in NFe)
                    {
                        notaXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><nfeProc versao=\"" + versao + "\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">" + nota.OuterXml + "</nfeProc>";
                        XmlNodeList infNFe = nota.GetElementsByTagName("infNFe");
                        string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");
                        File.WriteAllText(selectedFolder + "\\NOTAS\\" + chave + ".xml", notaXML);
                    }



                }

                OrganizeXml(label2, selectedFolder + "\\NOTAS", comboBox1);



            }
        }

        private static void OrganizeXml(Label label2, string selectedFolder, ComboBox comboBox1)
        {
            string folderMove = String.Empty;

            string folder = selectedFolder;

            label2.Text = "Arquivos sendo processados, aguarde...";
            label2.Refresh();

            string[] files = Directory.GetFiles(folder, "*.xml", SearchOption.AllDirectories);

            int i = 1, arquivos = files.Length;


            Directory.CreateDirectory(folder + @"\ORGANIZADO");
            if (comboBox1.SelectedIndex != 2)
            {
                Directory.CreateDirectory(folder + @"\ORGANIZADO\OUTROS");
                Directory.CreateDirectory(folder + @"\ORGANIZADO\LOTES");
            }
            foreach (string file in files)
            {
                XmlDocument xmlDocument = new XmlDocument();

                try
                {
                    xmlDocument.Load(file);
                    if (xmlDocument.DocumentElement.Name != "nfeProc")
                    {
                        XmlNodeList NFe = xmlDocument.GetElementsByTagName("NFe");
                        var nota = ((XmlElement) NFe[0]);
                        if (nota != null)
                        {
                            XmlNodeList infNFe = ((XmlElement) NFe[0]).GetElementsByTagName("infNFe");
                            string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");
                            string versao = infNFe[0].Attributes["versao"].Value;
                            string notaXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><nfeProc versao=\"" + versao +
                                             "\" xmlns=\"http://www.portalfiscal.inf.br/nfe\">" + nota.OuterXml +
                                             "</nfeProc>";
                            string dirNote = Path.GetDirectoryName(file);
                            File.WriteAllText(dirNote + "\\fix_" + chave + ".xml", notaXML);
                        }
                    }



                    //
                    //
                    //

                }
                catch (XmlException)
                {
                    XmlDocument doc = new XmlDocument();
                    string arquivo = ReadFileToString(file);
                    arquivo = RemoveSpecialCharacters(arquivo);
                    if (arquivo == "")
                    {
                        File.Move(file, folder + @"\ORGANIZADO\OUTROS\corrupt_" + Path.GetFileName(file));
                        continue;
                    }
                    try
                    {
                        doc.LoadXml(arquivo);
                        doc.PreserveWhitespace = true;
                        doc.Save(file);
                    }
                    catch (XmlException)
                    {
                        File.Move(file, folder + @"\ORGANIZADO\OUTROS\corrupt_" + Path.GetFileName(file));
                        files = files.Where(f => f != file).ToArray();
                    }
                }
            }

            foreach (string file in files)
            {

                string arquivoLoad = file;
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(arquivoLoad);
                XmlNodeList NFe = xmlDocument.GetElementsByTagName("NFe");
                XmlNodeList enviNFe = xmlDocument.GetElementsByTagName("enviNFe");



                if (NFe.Count == 0)
                {
                    if (File.Exists(folder + @"\ORGANIZADO\OUTROS\no_NFe_" + Path.GetFileName(arquivoLoad)))
                    {
                        Random rnd = new Random();
                        File.Copy(arquivoLoad,
                            folder + @"\ORGANIZADO\OUTROS\no_NFe_" + rnd.Next(1, 5000) + Path.GetFileName(arquivoLoad));
                    }
                    else
                    {
                        File.Copy(arquivoLoad, folder + @"\ORGANIZADO\OUTROS\no_NFe_" + Path.GetFileName(arquivoLoad));
                    }

                    continue;
                }

                XmlNodeList infNFe = ((XmlElement)NFe[0]).GetElementsByTagName("infNFe");
                string chave = infNFe[0].Attributes["Id"].Value.Replace("NFe", "");


                if (xmlDocument.DocumentElement.Name != "nfeProc")
                {
                    File.Move(arquivoLoad, folder + @"\ORGANIZADO\OUTROS\no_nfeProc_" + Path.GetFileName(arquivoLoad));
                    arquivoLoad = Path.GetDirectoryName(file) + "\\fix_" + chave + ".xml";
                }
                if (enviNFe.Count > 0)
                {
                    if (File.Exists(folder + @"\ORGANIZADO\LOTES\" + Path.GetFileName(arquivoLoad)))
                    {
                        Random rnd = new Random();
                        File.Copy(arquivoLoad, folder + @"\ORGANIZADO\LOTES\" + rnd.Next(1, 5000) + Path.GetFileName(arquivoLoad));
                    }
                    else
                    {
                        File.Copy(arquivoLoad, folder + @"\ORGANIZADO\LOTES\" + Path.GetFileName(arquivoLoad));
                    }

                    continue;
                }

                //XmlNodeList infNFe = ((XmlElement)NFe[0]).GetElementsByTagName("infNFe");
                XmlNodeList ide = ((XmlElement)infNFe[0]).GetElementsByTagName("ide");


                string tpNF = ((XmlElement)ide[0]).GetElementsByTagName("tpNF")[0].InnerText;

                //if (tpNF == "0") continue;


                XmlNodeList emit = ((XmlElement)infNFe[0]).GetElementsByTagName("emit");

                string emitInfoCod;

                if (((XmlElement)emit[0]).GetElementsByTagName("CNPJ").Count > 0)
                {
                    emitInfoCod = ((XmlElement)emit[0]).GetElementsByTagName("CNPJ")[0].InnerText;
                }
                else if (((XmlElement)emit[0]).GetElementsByTagName("CPF").Count > 0)
                {
                    emitInfoCod = ((XmlElement)emit[0]).GetElementsByTagName("CPF")[0].InnerText;
                }
                else
                {
                    emitInfoCod = "0";
                }

                string ide_dEmi = (((XmlElement)ide[0]).GetElementsByTagName("dEmi").Count > 0)
                    ? ((XmlElement)ide[0]).GetElementsByTagName("dEmi")[0].InnerText
                    : ((XmlElement)ide[0]).GetElementsByTagName("dhEmi")[0].InnerText;
                string[] data = ide_dEmi.Split('-');
                string folderName = data[0] + "\\" + data[1];
                string organizeStyle = String.Empty;

                if (comboBox1.SelectedIndex == 0 || comboBox1.SelectedIndex == 2)
                {
                    organizeStyle = folder + @"\ORGANIZADO\" + emitInfoCod + @"\" + folderName;
                }
                else
                {
                    organizeStyle = folder + @"\ORGANIZADO\" + folderName + @"\" + emitInfoCod;
                }


                if (!Directory.Exists(organizeStyle))
                {
                    Directory.CreateDirectory(organizeStyle);
                }
                folderMove = organizeStyle + "\\";




                if (!File.Exists(folderMove + chave + ".xml"))
                {
                    File.Copy(arquivoLoad, folderMove + chave + ".xml");
                }


                label2.Text = "Arquivos sendo processados, aguarde... (" + i + " / " + arquivos + ")";
                label2.Refresh();
                i++;


            }


            label2.Text = "Notas organizadas com sucesso!";
            label2.Refresh();
        }

        public static string ReadFileToString(string filePath)
        {
            using (StreamReader streamReader = new StreamReader(filePath))
            {
                string text = streamReader.ReadToEnd();
                streamReader.Close();
                return text;
            }

        }

        public static string RemoveSpecialCharacters(string str)
        {
            return Regex.Replace(str, @"[^\u0000-\u007F]", string.Empty);
        }

        private void exitBtn_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

我如何确定发生了什么?

1 个答案:

答案 0 :(得分:0)

指向引用类型的变量的值是而不是对象,它只是对象所在的内存地址。

因此,当您执行以下操作时:

while (true)
{
    var myVariable = new MyReferenceType();
}

你真正重用的唯一内存是变量本身(想象一下32或64位指针)。但是在每次迭代中,你在内存空间中的某个地方分配足以适应你刚创建的新对象,并且内存绝对不是为前一个对象保留的内存。

这基本上是您的内存使用量增长的原因。 &#34; old&#34;没有实时引用的先前迭代的对象最终将被GC收集,但如果GC确定它有足够的可用内存来避免它,则可能永远不会收集它。