Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 读取4000个文件后引发System.OutOfMemoryException_C#_Entity Framework_Sql Server 2012 - Fatal编程技术网

C# 读取4000个文件后引发System.OutOfMemoryException

C# 读取4000个文件后引发System.OutOfMemoryException,c#,entity-framework,sql-server-2012,C#,Entity Framework,Sql Server 2012,我们希望将52000个文件(.pdf,.xls,.doc…等)导入SQL Server 2012数据库 我有一个docsier\u fichier.txt文件,其中包含文件名。我将这些名称加载到一个集合中,然后循环此集合,并尝试在direcotryPiecesJointes中查找这些文件,并将它们转换为字节,然后使用以下代码将它们插入数据库: var dossierFichiers = addOrUpdateHelper.ReadEntities<DossierFichier, Dossi

我们希望将52000个文件(
.pdf
.xls
.doc
…等)导入SQL Server 2012数据库

我有一个
docsier\u fichier.txt
文件,其中包含文件名。我将这些名称加载到一个集合中,然后循环此集合,并尝试在direcotry
PiecesJointes
中查找这些文件,并将它们转换为字节,然后使用以下代码将它们插入数据库:

var dossierFichiers = addOrUpdateHelper.ReadEntities<DossierFichier, DossierFichierMap>("dossier_fichier.txt").ToArray();
// (2) Parcourir toutes les instances de DossierFichier chargées + Lire le fichier référencé + Le charger dans la propriété Fichier
var dirPath = System.IO.Path.Combine(Environment.CurrentDirectory, "piecesJointes");
var nbfichier = 0;

foreach (var df in dossierFichiers) {
    try {
        var path = System.IO.Path.Combine(dirPath, string.Concat( df.Code,"_", df.Nom));
        df.Fichier = File.ReadAllBytes(path);
        context.DossierFichier.Add(df);
        context.SaveChanges();

        Logger.Info("Le fichier {0} a été inséré", df.Nom);

        nbfichier++;
    } catch (FileNotFoundException ex) {
        Logger.Error("Fichier {0} : {1}", df.Nom, ex.Message);
    } catch (Exception ex) {
        Logger.Error("Fichier {0} : {1}",df.Nom, ex.Message);
    }
}
var-dossierfichers=addorupdatehelp.ReadEntities(“dossier_fichier.txt”).ToArray();
//(2)包裹商兜售档案保管员的实例+文件保管员的权利+文件保管员的权利+文件保管员的权利
var dirPath=System.IO.Path.Combine(Environment.CurrentDirectory,“片段点”);
var nbfichier=0;
foreach(档案编制者中的var df){
试一试{
var path=System.IO.path.Combine(dirPath,string.Concat(df.Code,“”,df.Nom));
df.Fichier=File.ReadAllBytes(路径);
上下文。档案编制者。添加(df);
SaveChanges();
Logger.Info(“lefichier{0}aétéinséré”,df.Nom);
nbfichier++;
}捕获(FileNotFoundException ex){
Logger.Error(“Fichier{0}:{1}”,df.Nom,ex.Message);
}捕获(例外情况除外){
Logger.Error(“Fichier{0}:{1}”,df.Nom,ex.Message);
}
}

插入4000个文件后,我得到了一个
OutOFMemoryException
,这花费了很多时间(60小时)。请您帮助我插入所有这些文件而不获取
OutOfmemoryException
,以及如何更快地插入这些文件?

对于集合中的每个项目,您可以将整个文件内容(字节数组)添加到
df.Fichier
。这是内存使用量增加的原因之一


您可以通过使用临时变量来解决此特定问题

您的代码似乎具有O(n2)性能,因为它将所有文件内容保留在内存中

  • 循环的第一次迭代将保存添加的第一个对象
  • 第二次迭代保存第二个对象并刷新第一个对象
  • 第三次迭代保存第三个对象并刷新前两个对象
  • 。。。等等
  • 第N次迭代插入第N个对象,并刷新以前插入的N-1个对象
您应该能够通过将更新“批处理”在一起解决此问题:

  • 添加到目前为止已插入的对象数
  • 不要调用
    context.SaveChanges()立即
  • 当插入的对象数达到100时,调用
    context.SaveChanges(),然后将
    上下文
    替换为新实例
这将确保所有对象只保存一次,到数据库的往返次数处于控制之下,并且内存中的对象不会超过100个

此外,通过将文件粘贴到
df.Fichier
中,可以保留文件内容。这可能会导致系统内存不足,因此您应该复制
df

var path = System.IO.Path.Combine(dirPath, string.Concat( df.Code,"_", df.Nom));
var dfCopy = new DossierFichier(df); // Copy df's fields
dfCopy.Fichier = File.ReadAllBytes(path);
context.DossierFichier.Add(dfCopy);

您的系统将没有无限内存,您可能需要定期将数据保存出来,然后再进行处理。或者甚至读一个文件,做你需要做的事情,然后从内存中删除它。我怎样才能显示它?如何从32位进程中运行的内存中删除它?另外,最好为每个插入创建新的实体框架上下文,并分别加载每个实体,不要重用上下文和实体。不知道什么是
docsierficher
我不知道。这取决于为什么需要这些文件字节。如果你只是读取字节并将它们存储在某个地方,我的答案将不同于你是否需要程序长度的所有内存。就这样。出于好奇,文件的平均大小是多少?或者只是为每次更新创建新的上下文,通常也可以。您可能也应该注意将字节保存在内存中,即
df.Fichier=File.ReadAllBytes(path)即使使用您描述的更新,由于所有这些字节都在内存中,仍有可能内存不足。@如果您是对的,我没有意识到内容保存在循环变量的
Fichier
字段中。谢谢你的评论!我为每个文件添加了一个DbContext,但仍然有outofmemoryexception@amina诀窍是确保先前文件的
DbContext
s在不再需要时被丢弃,并且在调用
context.SaveChanges()时设置
df.Fichier=null
已成功返回。创建字节后如何释放内存?我为每个文件添加了DbContext,但仍有outofmemoryexception@Evk我为每个文件添加了一个DbContext,但仍然存在outofmemory异常