IO FileStream и StreamReader в Powershell возвращают ноль, в то время как в c# это работает - PullRequest
0 голосов
/ 20 марта 2020

Я создал сценарий в C# и по личным причинам я хотел бы преобразовать его в PowerShell.

После многих попыток я все еще не могу понять, почему он все еще дает мне эту ошибку, что-то не так с кодом?

" Невозможно вызвать метод в выражении Null. " | когда я вызываю $ reader.ReadLine ()

Цели этого сценария - прочитать файл .log и найти полезную информацию для отправки их в базу данных MongoDB.

C#

            string level = "", username = "", date = "", solutionName = "", message = "";
        FileStream logFileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
        StreamReader reader = new StreamReader(logFileStream);

        int compteur = 0;

        while (compteur < lineCount-1)
        {
            bool info = true;
            string messagelog = "";
            int tmpCompteur = 0;
            // open the file to read it
            reader = File.OpenText(filePath);
            // take the log message (could be multiple lines)
            for (int i = 0; i < lineCount; i++)
            {
                string line = reader.ReadLine();
                if (Regex.IsMatch(line, "INFO") || Regex.IsMatch(line, "ERROR"))
                {
                    if (info)
                        info = !info;
                    else
                        break;
                }
                messagelog += line;
                tmpCompteur++;
                compteur++;
            }

            // Regex to find the log Level, UserName, Date, SolutionName, Message
            if (Regex.IsMatch(messagelog, "INFO") || Regex.IsMatch(messagelog, "ERROR"))
                level = Regex.Match(messagelog, "INFO").Value;
            if (Regex.IsMatch(messagelog, "-(.*?)-"))
                username = Regex.Match(messagelog, "-(.*?)-").Value.Substring(1, Regex.Match(messagelog, "-(.*?)-").Value.Length - 2);
            if (Regex.IsMatch(messagelog, "([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]:[0-6][0-9]"))
                date = Regex.Match(messagelog, "([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]:[0-6][0-9]").Value;
            if (Regex.IsMatch(messagelog, "\\[E(.*?)\\]"))
                solutionName = Regex.Match(messagelog, "\\[E(.*?)\\]").Value;
            if (Regex.IsMatch(messagelog, "\\]\\s.*"))
                message = Regex.Match(messagelog, "\\]\\s.*").Value.Substring(2);

            // close the reader because we don't need it anymore
            reader.Close();
            // convert our data to an object to send it to MongoDB
            var Data = new BsonDocument
            {
                { "Date", DateTime.ParseExact(date, "dd/MM/yyyy HH:mm:ss", null) },
                { "Level", level},
                { "Message", message},
                { "UserName", username}
            };
            // send data to MongoDB
            collection.InsertOneAsync(Data);
            // delete the lines already processed by our programm
            File.WriteAllLines(filePath, File.ReadAllLines(filePath).Skip(tmpCompteur).ToArray());
        }
        // close the fileStream
        logFileStream.Close();
        // delete the file
        File.Delete(filePath);
    }

PowerShell

   [string]$level
   [string]$userName
   [string]$date
   [string]$solutionName
   [string]$message

   $logFileStream = New-Object System.IO.FileStream $filePath, ([System.IO.FileMode]::Append), ([System.IO.FileAccess]::Write), ([System.IO.FileShare]::Read)
   $reader = New-Object System.IO.StreamReader $logFileStream
   # https://github.com/nightroman/Mdbc
   Connect-Mdbc -ConnectionString $iniContent["MongoDB"]["Server"] -DatabaseName $iniContent["MongoDB"]["Database"] -CollectionName $iniContent["MongoDB"]["Collection"]
   $pbar_LoadFile.Visible = $true
   [int]$compteur = 0
   while ($compteur -clt $linesCount) {

       [bool]$info = $true 
       [string]$messageLog = ""
       [int]$tmpCompteur = 0
       $reader = $IOFile::OpenText($filePath)
       for ([int]$i = 0; $i -lt $linesCount; $i++) {

           $line = $reader.ReadLine() 
           if ($line -match "INFO") {

               if ($info -eq $true) {

                   $info = $false 
               }
               else {
                   break 
               }
           }
           $messageLog += $line 
           $tmpCompteur++
           $compteur++ 
       }


       if ($messageLog -match "INFO") {

           $level = $matches[0]
       }
       if ($messageLog -match "-(.*?)-") {

           $userName = $matches[0].Substring(1, $matches[0].length - 2)
       }
       if ($messageLog -match "([1-9]|([012][0-9])|(3[01]))\/([0]{0,1}[1-9]|1[012])\/\d\d\d\d [012]{0,1}[0-9]:[0-6][0-9]:[0-6][0-9]") {

           $date = $matches[0]
       }
       if ($messageLog -match "    ") {

           $solutionName = $matches[0]
       }
       if ($messageLog -match "\]\s.*") {

           $message = $matches[0].Substring(2) 
       }
       $reader.Close()       
       @{Date = Convert-ToDateTime($date); Level = $level; Message = $message; UserName = $userName } | Add-MdbcData
       (Get-Content $filePath | Select-Object -Skip $tmpCompteur) | Set-Content $filePath
   }
   $logFileStream.Close()
   Remove-Item $filePath
   $pbar_LoadFile.Value += 1
}

1 Ответ

0 голосов
/ 20 марта 2020

Вы неправильно понимаете System.IO.StreamReader как $ IOFile. Сначала вы должны объявить это внутри $ reader следующим образом:

$reader = New-Object -TypeName System.IO.StreamReader -ArgumentList $filePath

В powershell. NET Типы называются так:

[System.IO.File]

Их методы stati c вызывается путем размещения двух двоеточий после].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...