kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

ロックしないでファイル読み込み

少し特殊ですが、ファイルをロックしないで読み込みしたくなりました。PowerShellで実装してみましたので、メモしておきます。

実装方法

ファイルをロックせずに、ファイル内容を標準出力します。ポイントは、ファイルオープン時に指定するFileShareのReadWrite、Deleteです。

$inpath = 'D:\tmp\dummy.txt'
$sr = [System.IO.StreamReader]::new(
    [System.IO.FileStream]::new(
        $inpath,
        [System.IO.FileMode]::Open,
        [System.IO.FileAccess]::Read,
        # 他プログラムの読み書き、削除をロックしない
        [System.IO.FileShare]::ReadWrite + [System.IO.FileShare]::Delete))
echo $sr.ReadToEnd()
$sr.Close()

ファイルオープン部分は、次のように書くこともできますね。

$fs = [System.IO.File]::Open(
    $inpath,
    [System.IO.FileMode]::Open,
    [System.IO.FileAccess]::Read,
    [System.IO.FileShare]::ReadWrite + [System.IO.FileShare]::Delete)
$sr = [System.IO.StreamReader]::new($fs)

テキスト読み込み部分は、次のようにして、1行ごとに処理することもできますね。

while (($line = $sr.ReadLine()) -ne $null) {
    echo $line
}

ワンライナー

Windowsコマンドプロンプトから、ワンライナーで実行する場合は、次のように書けました。

powershell -Command "$sr = [System.IO.StreamReader]::new([System.IO.FileStream]::new('D:\tmp\dummy.txt', [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite + [System.IO.FileShare]::Delete)); echo $sr.ReadToEnd(); $sr.Close()"

動作確認方法

上述のファイル読み込み中に、ロックがかかっていないことを動作確認するときは、読み込み処理の途中で、Start-Sleep 10(10秒のスリープ)などを入れると便利です。当プログラムを実行して、スリープ中に、他のプログラムから読み書き、削除ができることを確認できるはずです。なお、他のプログラムがファイル削除した場合、削除処理成功しますが、ファイルはまだ残っていて、当プログラムがファイルクローズ後に、ファイルが削除されました。

動作確認環境

参考