リソースの開放について
StreamReader
などでファイルをOpenした場合、Close()
を忘れたり、Close()
前にエラーで処理が終了してしまうとファイルがオープンされたままになります。
1
2
3
4
5
6
7
8
9
|
# Close()を実行していない例
$filePath = "C:\test.txt"
$sr = New-Object System.IO.StreamReader($filePath)
while(($line = $sr.ReadLine()) -ne $null) {
Write-Host $line
}
# $sr.Close()
|
上記スクリプト実行後、テキストエディターで該当ファイルを開こうとするとエラーメッセージが表示されます。
C:\test.txt は現在他のプロセスによって書き込みが禁止されてます。
PowerShellの自動リソース開放
C#ではUsing
、Javaではtry-with-resources
といった自動でリソース開放する構文が存在します。
PowerShellには自動でリソースを開放する構文は存在しませんが、以下サイトに公開されているUsing-Object
を使用すると自動リソース開放が可能となります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
function Using-Object {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[AllowEmptyString()]
[AllowEmptyCollection()]
[AllowNull()]
[Object]
$InputObject,
[Parameter(Mandatory = $true)]
[scriptblock]
$ScriptBlock
)
try {
. $ScriptBlock
}
finally {
if ($null -ne $InputObject -and $InputObject -is [System.IDisposable]) {
$InputObject.Dispose()
}
}
}
|
Using-Object
を使用するとIDisposable
を実装するオブジェクトはClose()
やDispose()
を実行しなくても自動でリソースが開放されます。
1
2
3
4
5
6
7
8
|
$filePath = "D:\test.txt"
# 自動でリソースが開放される
Using-Object($sr = New-Object System.IO.StreamReader($filePath)) {
while(($line = $sr.ReadLine()) -ne $null) {
Write-Host $line
}
}
|