处理文件时内存使用量增加
本文关键字:使用量 增加 内存 文件 处理 | 更新日期: 2023-09-27 18:06:37
我正在开发一个应用程序,它读取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();
}
}
}
我怎么知道发生了什么?
指向引用类型的变量的值根本不是对象,它只是该对象所在的内存地址。
所以当你做以下操作时:
while (true)
{
var myVariable = new MyReferenceType();
}
你真正重用的唯一内存是变量本身(想想32位或64位指针)。但是在每次迭代中,你都要分配足够的内存空间来容纳你刚刚创建的新对象,并且这些内存绝对不是为前一个对象保留的内存。
这就是内存使用增长的本质原因。以前迭代中没有活动引用的"旧"对象最终将被GC收集,但如果GC认为它有足够的可用内存来避免它,则可能永远不会收集。