kazuakix の日記

Windows Phone とか好きです

StreamReader が最後にストリームを閉じていた件 (2)

昨日は StreamReader がストリームを閉じちゃうので、先に CopyToAsync() で保存してから読み込むという安直な対応をしたのですが、読み込んだ結果によって保存する・しないを決めたかったので ちゃんと対応する事にしました。
 
使用するコンストラクタはこちら

public StreamReader(
	Stream stream,
	Encoding encoding,
	bool detectEncodingFromByteOrderMarks,
	int bufferSize,
	bool leaveOpen
)

ストリームの他に 使用する文字エンコーディング、 ファイルの先頭にあるバイト順序マークを検索するかどうか、 最小バッファー サイズを指定したうえでやっと 読み終わった後にストリームを開いたままにするかどうか を指定することができます。

今回はシフト JIS を読み込みたいので 文字エンコーディングは以前用意した自前エンコーディングを使用して、バイト順序マークの検索は不要です。

問題は最少バッファーサイズですが、なぜか機械翻訳から外されている解説によると 128 文字以上の文字数を指定するようです。

The buffer size, in number of 16-bit characters, is set by the bufferSize parameter. If bufferSize is less than the minimum allowable size (128 characters), the minimum allowable size is used.

同じページの例では 512 が指定されているようなので、ひとまずこの値で試してみることにしました。
 
昨日のコードはこんな感じになるのでしょうか。

public async Task GetData()
{
    try
    {
        using (var req = new HttpClient())
        using (var res = await req.GetAsync("http://~"))
        {
            if (res.IsSuccessStatusCode)
            {
                var err    = false;
                var stream = await res.Content.ReadAsStreamAsync();

                // 読み込み
                var sjis = MyEncoding.GetSjisEncoding();
                using (var reader = new StreamReader(stream, sjis, false, 512, true))
                {
                    while (!reader.EndOfStream)
                    {
                        var row = reader.ReadLine();
                        // アカンときは err をセット
                    }
                }

                // ローカルに保存
                if (!err)
                {
                    var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
                        "file.txt", CreationCollisionOption.ReplaceExisting);
                    using (var local = await file.OpenStreamForWriteAsync())
                    {
                        await stream.CopyToAsync(local);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        Debug.Assert(false, ex.Message);
    }
}

 
とりあえずは動いていますが、適切なバッファサイズは検証しないといけないですね。