C# 读取更多1gb的文件,并将内容存储在字符串/列表或任何可以在RAM中轻松处理的内容中

C# 读取更多1gb的文件,并将内容存储在字符串/列表或任何可以在RAM中轻松处理的内容中,c#,file-io,C#,File Io,我的代码在下面,只是用了太多,现在的文件大小是700 mb的txt格式 StringBuilder dogs = new StringBuilder(); StreamReader str = new StreamReader(file); while ((line = str.ReadLine()) != null) { dogs.AppendLine(line); } 任何人都可以建议我以任何数据类型存储文件,但我必须在读取并对其执行操作并以csv格式逐行存储数据后写入文件我建议逐

我的代码在下面,只是用了太多,现在的文件大小是700 mb的txt格式

StringBuilder dogs = new StringBuilder();
StreamReader str = new StreamReader(file);
while ((line = str.ReadLine()) != null)
{
    dogs.AppendLine(line);
}

任何人都可以建议我以任何数据类型存储文件,但我必须在读取并对其执行操作并以csv格式逐行存储数据后写入文件

我建议逐行读取文件,处理每行中的数据并将其写入另一个文件流,这样就不需要将完整的数据写入内存


如果需要将过去的行数据用于处理当前行中的数据,或者需要遍历所有行以提取一些信息,则我建议将每行保存到数据库中,然后处理数据/更新数据库中的行,最后再次检索以准备csv文件

在具有足够RAM的64位系统上,这应该可以:

List<string> dogs = new List<string>();
StreamReader str = new StreamReader(file);
while ((line = str.ReadLine()) != null)
{
    dogs.Add(line);
}
List dogs=new List();
StreamReader str=新的StreamReader(文件);
而((line=str.ReadLine())!=null)
{
添加(行);
}

对于您的电子邮件场景,我强烈建议您使用任何SQL数据库

您应该逐行读取第一个文件并将其解析到数据库表中,然后使用SQL查询从第二个文件中搜索电子邮件。或者,您甚至可以将这两个文件解析为单独的表,并使用SQL查询来获取类似的记录


如果您不想麻烦SQL查询和MS Access,我建议您使用SQLite和ORM库。

这里是一个暴力版本。糟糕的是,您正在为file1中的每一行迭代所有file2行。但你也会在记忆中这样做。最好的解决方案是将文件导入到RDBMS中,您可以在其中使用索引

这是一次性练习吗?使用文件差异工具(如WinDiff或Beyond Compare)怎么样

或者这个怎么样:


当您从比较文件中读取电子邮件时,您可以计算并存储每封电子邮件的哈希值,而不是存储每封电子邮件的内容

现在,当您从另一个文件中读取电子邮件时,您再次计算每个电子邮件的哈希值,并从上一次传递中搜索哈希列表。如果找到了散列,您就知道电子邮件出现在第一个文件中

由于散列值往往比原始文本小得多(例如,SHA-1散列值每个为140字节),因此散列值的集合应该很容易放入RAM中

下面的示例假设每行文本存储一封电子邮件

using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

var exclude = new List<byte[]>();

var sha1 = new SHA1CryptoServiceProvider();

// read exclusion emails
using (var sr = new StreamReader("exclude-file")) {
    string email;
    // assume one email per line of text
    while ((email = sr.ReadLine()) != null) {
        exclude.Add(sha1.ComputeHash(new MemoryStream(Encoding.UTF8.GetBytes(email))));
    }
}

// read emails
using (var sr = new StreamReader("email-file")) {
    string email;
    // again, assume one email per line of text
    while ((email = sr.ReadLine()) != null) {
        if (exclude.Contains(sha1.ComputeHash(new MemoryStream(Encoding.UTF8.GetBytes(email))))) {
            // exclusion file contains email
        } else {
            // exclusion file does not contain email
        }
    }
}
使用System.Collections.Generic;
使用System.IO;
使用System.Security.Cryptography;
使用系统文本;
var exclude=新列表();
var sha1=新的SHA1CryptoServiceProvider();
//阅读排除邮件
使用(var sr=new StreamReader(“排除文件”)){
字符串电子邮件;
//假设每行文本有一封电子邮件
而((email=sr.ReadLine())!=null){
exclude.Add(sha1.ComputeHash(newmemoryStream(Encoding.UTF8.GetBytes(email)));
}
}
//阅读电子邮件
使用(var sr=新的StreamReader(“电子邮件文件”)){
字符串电子邮件;
//同样,假设每行文本有一封电子邮件
而((email=sr.ReadLine())!=null){
if(exclude.Contains(sha1.ComputeHash)(新的MemoryStream(Encoding.UTF8.GetBytes(email ')))){
//排除文件包含电子邮件
}否则{
//排除文件不包含电子邮件
}
}
}


您真的需要在内存中完成它吗?你可以开始一行一行地读它,做你想做的任何事情,然后不完整地写下来。你为什么一次要全部?这是什么类型的文件?这个文件是内部维护的吗?700mb的文件是巨大的。分成多个较小的文件,然后读取它们。我有两个文件,必须比较两个文件。让我们假设一个例子,两个文件都包含电子邮件,现在我已经删除了第一个文件中的所有电子邮件,该文件存在于第二个文件中,第二个文件的大小可能是1gb,但第一个电子邮件文件总是超过1gb。因此,这就是为什么我必须将第二个文件保存在内存中以备露营之用。我怀疑您是否需要立即将其全部保存在内存中。是否有任何解决方案可以提供给David Heffernamid先生,将1gb文件保存在数据库中是一种方便的方法,因为保存后,我必须与另一个文件进行比较,如果您有,这将在StreamReader中逐行读取在DB中比较每行的一些唯一标识符会快得多。在DB中保存每行然后在任何数据类型中保存会快吗?在DB中保存会快些,然后在内存中保存会快些,但即使在将来这些文件可能增长时,也不会出现任何与内存不足相关的问题。K我明白你的意思,MS Access数据库是否可以处理2 GB的数据?我在32位计算机上尝试过,但对于745 mb的文件,仍然会消耗超过1.5GB的RAM。如果大小增加一倍,可能是由于ANSI-->Unicode转换。任何其他建议,如果使用更少的空间,MS Access是否可以处理1 GB的数据或100万字节的数据emails@user2431786你试过了吗?它将根据您正在使用的机器的资源、磁盘空间和RAM来处理它。。但我现在所做的是因为文件大小太大,所以在读取所有文件数据时对第二个文件进行排序,而当第一个文件数据读取并与另一个文件进行比较时,比较所需的时间更少。。这就是为什么我不能一次又一次地读取第二个文件的原因,因为它占用了太多的时间……你能为@Ferruccio提供一些例子吗?我正在尝试将同一个文件与你的代码进行比较,但如果语句即使在同一个文件中也不会出现真的话。。。
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

var exclude = new List<byte[]>();

var sha1 = new SHA1CryptoServiceProvider();

// read exclusion emails
using (var sr = new StreamReader("exclude-file")) {
    string email;
    // assume one email per line of text
    while ((email = sr.ReadLine()) != null) {
        exclude.Add(sha1.ComputeHash(new MemoryStream(Encoding.UTF8.GetBytes(email))));
    }
}

// read emails
using (var sr = new StreamReader("email-file")) {
    string email;
    // again, assume one email per line of text
    while ((email = sr.ReadLine()) != null) {
        if (exclude.Contains(sha1.ComputeHash(new MemoryStream(Encoding.UTF8.GetBytes(email))))) {
            // exclusion file contains email
        } else {
            // exclusion file does not contain email
        }
    }
}