我得到内存异常“System.IO.out异常”错误

时间:2013-04-03 10:00:38

标签: c#

对于小目录大小代码工作正常,当目录文件的大小很大时,它会给出此错误消息。

我的代码:

IEnumerable<string> textLines = 
          Directory.GetFiles(@"C:\Users\karansha\Desktop\watson_query\", "*.*")
                   .Select(filePath => File.ReadAllLines(filePath))
                   .SelectMany(line => line)
                   .Where(line => !line.Contains("appGUID: null"))
                   .ToList();

List<string> users = new List<string>();

textLines.ToList().ForEach(textLine =>
{
    Regex regex = new Regex(@"User:\s*(?<username>[^\s]+)");
    MatchCollection matches = regex.Matches(textLine);
    foreach (Match match in matches)
    {
        var user = match.Groups["username"].Value;
        if (!users.Contains(user)) 
            users.Add(user);
    }
});

int numberOfUsers = users.Count(name => name.Length <= 10);
Console.WriteLine("Unique_Users_Express=" + numberOfUsers);

2 个答案:

答案 0 :(得分:1)

我会使用Directory.EnumerateFilesFile.ReadLines,因为它们的内存较少,它们的工作方式类似于StreamReader,而Directory.GetFilesFile.ReadAllLines会将所有内容读入内存第一:

var matchingLines = Directory.EnumerateFiles(@"C:\Users\karansha\Desktop\watson_query\", "*.*")
    .SelectMany(fn => File.ReadLines(fn))
    .Where(l => l.IndexOf("appGUID: null", StringComparison.InvariantCultureIgnoreCase) >= 0);
foreach (var line in matchingLines)
{
    Regex regex = new Regex(@"User:\s*(?<username>[^\s]+)");
    // etc pp ...
}

您也无需再次为所有行创建List<string>。只需使用foreach枚举查询(textLines.ToList创建第三个也是多余的集合。)

答案 1 :(得分:0)

尝试使用下一个代码,它使用ReadLines,它不会将整个文件加载到内存中,而是逐行读取文件。它还使用HashSet来存储匹配正则表达式的唯一结果。

Regex regex = new Regex(@"User:\s*(?<username>[^\s]+)");
IEnumerable<string> textLines = 
      Directory.GetFiles(@"C:\Users\karansha\Desktop\watson_query\", "*.*")
               .Select(filePath => File.ReadLines(filePath))
               .SelectMany(line => line)
               .Where(line => !line.Contains("appGUID: null"));

HashSet<string> users = new HashSet<string>(
    textLines.SelectMany(line => regex.Matches(line).Cast<Match>())
             .Select(match => match.Groups["username"].Value)
);

int numberOfUsers = users.Count(name => name.Length <= 10);
Console.WriteLine("Unique_Users_Express=" + numberOfUsers);