0

このコード文字列xでは、OutOfMemoryException. 取得せずにすべてのファイルを解析できる他の方法はありますOutofMemoryExceptionか? 私が試したコードには何も問題はないようです。

誰かが、ファイル全体を読み取って 1 つの文字列に入れるのではなく、ファイルごとにプログラムを読み取るようにすることを提案しました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

各ファイルのすべての行を結合したいというのは奇妙に思えます。ユーザー名が一線を越えないと仮定すると、これを 1 つの 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);

うまくいけば、クエリの各行が明確になるはずです。これは一度に 1 行ずつ処理されます。ユーザー名の単純なリストがメモリに収まらないほど多くのユーザーがいない限り、問題ありません。カウントだけが必要な場合は、 への呼び出しも必要ありません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 に答える