nonrecurring
nonrecurring

Reputation: 43

How can I make a StreamReader Open/Read/Close process into a function

In Powershell, I frequently use a StreamReader to iterate over files and read/manipulate text. Instead of constantly having to type a script similar to:

## StreamReader setup / file availability check

try {
    ## Create Stream Reader
    $readStream = [System.IO.StreamReader]::new($Path)

    ## Do stuff ...

} finally {
    $readStream.close()
} 

How can I make the entire setup/open/close process into a function that I can call whenever I need to automate the 'Do Stuff' portion of my above code? I am aware of how to make functions but I cant figure out how to turn this into a usable function so I only have to write it and edit it once but can use many times.

Upvotes: 1

Views: 1167

Answers (2)

mklement0
mklement0

Reputation: 439113

Assuming that you want to process your text files line by line:

There's no need to deal with [System.IO.StreamReader] instances directly - you can use PowerShell's built-in features.

  • In the simplest case, if performance isn't paramount, combine Get-Content with ForEach-Object:

    Get-Content $Path | ForEach-Object { <# Do Stuff with $_, the line at hand #> }
    
  • When performance matters, use a switch statement with the -File parameter:

    switch -File $Path { Default { <# Do Stuff with $_, the line at hand #> } }
    

Upvotes: 0

RetiredGeek
RetiredGeek

Reputation: 3168

This may not be the most elegant solution but it does work.

You have different Functions for each type of processing I just called my test Process-Stream.

Function Process-Stream {

  Do {
  
    $Line = $readStream.ReadLine()
    "$Line"
  
  } While ($readStream.EndOfStream -eq $False)

} #End Function Process-Stream

Next you have a function that does all of your setup and error processing for the Stream.

Function Get-Stream {

  Param (
    [Parameter(Mandatory=$True)]
      [String] $SourcePath,
    [Parameter(Mandatory=$True)]
      [String] $ProcessFunction
  )
  
  try {
      ## Create Stream Reader
      $readStream = [System.IO.StreamReader]::new(
         "$SourcePath")
  
      & $ProcessFunction
  
  } finally {
      $readStream.close()
  }
  
} #End Function Get-Stream

Now you just call Get-Stream with the name of your processing function.

PS> Get-Stream -SourcePath "G:\Test\StreamIOTest.txt" -ProcessFunction Process-Stream
Line 1 
Line 2
Line 3
Line 4

PS>

Note: the test text file I used had 4 lines. Don't forget you need to have the functions loaded!

Updated: I realized after I posted that I should have parameterized the file to be read and passed that into Get-Stream also.

HTH

Upvotes: 1

Related Questions