0

在此代码字符串x中给出了一个OutOfMemoryException. 有没有其他方法可以解析所有文件而无需获取OutofMemoryException?我尝试过的代码似乎没有任何问题。

有人建议让程序逐个文件读取,而不是读取整个文件并将其放在一个字符串x中。

IEnumerable<string> textLines = Directory.GetFiles(@"C:\Users\karansha\Desktop\Unique_Express\", "*.*")
    .Select(filePath => File.ReadLines(filePath))
    .SelectMany(line => line);

string x = string.Join(",", textLines);
List<string> users = new List<string>();
Regex regex = new Regex(@"User:\s*(?<username>.*?)\s");
MatchCollection matches = regex.Matches(x);
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 < 15); 
Console.WriteLine("Unique_Users_Express=" + numberOfUsers);
4

2 回答 2

5

您希望将每个文件的所有行连接在一起似乎很奇怪。假设用户名不跨行,您可以在单个 LINQ 查询中以更简洁的方式执行此操作:

var regex = new Regex(@"User:\s(?<username>[^\s]+)");
var path = @"C:\Users\karansha\Desktop\Unique_Express\";
var users = Directory.GetFiles(path, "*.*")
                     .Select(file => File.ReadLines(file))
                     .SelectMany(lines => lines)
                     .SelectMany(line => regex.Matches(line).Cast<Match>())
                     .Select(match => match.Groups["username"].Value)
                     .Distinct()
                     .ToList();

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

希望查询的每一行都应该清楚。这将一次处理一行 - 只要您没有太多用户以至于不同用户名的简单列表不适合内存,您应该没问题。如果你需要计数,你甚至不需要调用ToList.

请注意,经过一些试验,我已经调整了正则表达式 - 我希望这对你来说没问题。

于 2013-03-12T13:35:10.553 回答
0

试试这个:假设用户名没有转到另一行,您可以解析每一行并建立唯一的用户名。我没有尝试像这样更改您的代码。只是它的逻辑。

        IEnumerable<string> textLines = Directory.GetFiles(@"C:\Users\karansha\Desktop\Unique_Express\", "*.*")
                                                 .Select(filePath => File.ReadLines(filePath))
                                                 .SelectMany(line => line);

        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 < 15);
        Console.WriteLine("Unique_Users_Express=" + numberOfUsers);
于 2013-03-12T13:39:31.240 回答