2016-03-14 2 views
1

Пробыв некоторое время в поисках наиболее четким способ проверить, если тело файла имеет такое же количество разделителей как заголовок я придумал этот код:Повышение производительности для проверки файла разделители

Param #user enters the directory path and delimiter they are checking for 
(
    [string]$source, 
    [string]$delim 
) 

#try { 
$lineNum = 1 
$thisOK = 0 
$badLine = 0 
$noDelim = 0 
$archive = ("*archive*","*Archive*","*ARCHIVE*"); 

foreach ($files in Get-ChildItem $source -Exclude $archive) #folder directory may have sub folders, as a temp workaround just made sure to exclude any folder with archive 
{ 
    $read2 = New-Object System.IO.StreamReader($files.FullName) 
    $DataLine = (Get-Content $files.FullName)[0] 
    $validCount = ([char[]]$DataLine -eq $delim).count #count of delimeters in the header 
    $lineNum = 1 #used to write to host which line is bad in file 
    $thisOK = 0 #used for if condition to let the host know that the file has delimeters that line up with header 
    $badLine = 0 #used so the write-host doesnt meet the if condition and write the file is ok after throwing an error 

    while (!$read2.EndOfStream) 
    { 
     $line = $read2.ReadLine() 
     $total = $line.Split($delim).Length - 1; 

     if ($total -eq $validCount) 
     { 
      $thisOK = 1 
     } 
     elseif ($total -ne $validCount) 
     { 
      Write-Output "Error on line $lineNum for file $files. Line number $lineNum has $total delimeters and the header has $validCount" 
      $thisOK = 0 
      $badLine = 1 
      break; #break or else it will repeat each line that is bad 
     } 
     $lineNum++ 
    } 
    if ($thisOK = 1 -and $badLine -eq 0 -and $validCount -ne 0) 
    { 
     Write-Output "$files is ok" 
    } 
    if ($validCount -eq 0) 
    { 
     Write-Output "$files does not contain entered delimeter: $delim" 
    } 
    $read2.Close() 
    $read2.Dispose() 
} #end foreach loop 
#} catch { 
# $ErrorMessage = $_.Exception.Message 
# $FailedItem = $_.Exception.ItemName 
#} 

Он работает для того, что я тестировал до сих пор. Однако, когда дело доходит до больших файлов, это занимает значительно больше времени. Мне было интересно, что я могу сделать или изменить для этого кода, чтобы быстрее обработать эти текстовые/CSV-файлы?

Кроме того, мои try..catch заявления закомментированы, так как сценарий, кажется, не запускается, когда я их включаю - никакая ошибка просто не входит в новую командную строку. Как я думал, я хотел бы включить простой графический интерфейс для других пользователей, чтобы дважды проверить.

Пример файла:

HeaderA|HeaderB|HeaderC|HeaderD   //header line 
DataLnA|DataLnBBDataLnC|DataLnD|DataLnE //bad line 
DataLnA|DataLnB|DataLnC|DataLnD|   //bad line 
DataLnA|DataLnB|DataLnC|DataLnD   //good line

Теперь, когда я смотрю на это, я предполагаю, что может быть проблемой, где есть правильная сумма, если разделители, но столбцы не соответствуют так:

HeaderA|HeaderB|HeaderC|HeaderD 
DataLnA|DataLnBDataLnC|DataLnD|
+0

Образец файлов с их «ограничителей» поможет прояснить, что вы спрашиваете, в настоящее время я я с трудом понимаю, чего вы пытаетесь достичь. – Kev

+0

Считается, что хороший вопрос задает этикет на SO, чтобы _ful_ indent ваш код. Это делает его более читаемым для потенциальных ответчиков. В общем, настоятельно рекомендуется прочитать информацию в разделе справки о том, как написать хороший вопрос. –

+0

У вас уже есть «StreamReader». Почему вы используете 'Get-Content' для чтения первой строки? –

ответ

0

Основная проблема, которую я вижу, заключается в том, что вы дважды читаете файл - один раз с вызовом Get-Content, который считывает весь файл в память и второй раз с вашим циклом while. Вы можете удвоить скорость вашего процесса, заменив строку:

$DataLine = (Get-Content $files.FullName)[0] #inefficient 

с этим:

$DataLine = Get-Content $files.FullName -First 1 #efficient 
+0

Спасибо, я думаю, я был слишком ленив, когда дело дошло до написания этой части. Это сработало, поэтому я буду придерживаться этого. – Dave

+0

Рад помочь! – JamesQMurphy

 Смежные вопросы

  • Нет связанных вопросов^_^