プログラミングしよう!ということでVisual Studioに入門中です。以前、Visual Studio Expressをダウンロードして少し触った程度ですが、敷居の高さに断念していました。
今回はVisual Studio 2019の製品版を購入して試しています。結構何が何だかわからないところからのスタートなので、メモがてらいろいろ残していきます。
System.IOのFileクラス
Using System.IO;
で使えるようになるFileクラスのメソッドを使ってファイルの読み書きをします。
ファイルを読むだけでも似たようなメソッドがいっぱい・・・。

ReadAllText
public static string ReadAllText (string path, System.Text.Encoding encoding);
encodingの設定はEncodeクラス。

// Create two different encodings. Encoding ascii = Encoding.ASCII; Encoding unicode = Encoding.Unicode; Encoding enc = Encoding.GetEncoding(1253); Encoding altEnc = Encoding.GetEncoding("windows-1253"); // Get a UTF-32 encoding by codepage. Encoding e1 = Encoding.GetEncoding( 12000 ); // Get a UTF-32 encoding by name. Encoding e2 = Encoding.GetEncoding( "utf-32" ); // Check their equality. Console.WriteLine( "e1 equals e2? {0}", e1.Equals( e2 ) );
GetEncodingメソッドを呼び出して、引数は数値もしくは文字コード文字列。日本語関連で書く場合は、
- 932 shift_jis ― Japanese (Shift-JIS)
- 10001 x-mac-japanese ― Japanese (Mac)
- 20290 IBM290 ― IBM EBCDIC (Japanese katakana)
- 20932 EUC-JP ― Japanese (JIS 0208-1990 and 0212-1990)
- 50220 iso-2022-jp ― Japanese (JIS)
- 50221 csISO2022JP ― Japanese (JIS-Allow 1 byte Kana)
- 50222 iso-2022-jp ― Japanese (JIS-Allow 1 byte Kana – SO/SI)
- 51932 euc-jp ― Japanese (EUC)
- 65000 utf-7 ― Unicode (UTF-7)
- 65001 utf-8 ― Unicode (UTF-8)
- 1200 utf-16 ― Unicode
- 1201 unicodeFFFE ― Unicode (Big endian)
- 12000 utf-32 ― Unicode (UTF-32)
- 12001 utf-32BE ― Unicode (UTF-32 Big endian)
が指定できる。Unicode系はおいておいて、日本語コードは本当に複雑・・・。
EUC-JP(20932)とeuc-jp(51932)はいずれもマイクロソフトが作ったコードナンバーのよう。基本的にはSHIFT-JISで使われている文字コードセットと同じものを、制御文字列が入り込まないように配置したもので、EUCはUNIXで使われることがおおいので、Unixサーバーいじるときにはちょっと注意が必要かも。基本的にはUTF-8かSHIFT-JISでよいと思われる。
Stringでの入力の場合には基本これ。今回読み込みたいファイルはテキストだが、行区切りが0x0D<CR>でWindows標準の0x0D0A<CRLF>ではないですが、たぶん0x0Aは無視されるはずなので問題ないはず。Windowsのメモ帳アプリでもレジストリをいじる必要があるけれど対応した模様。


使用する.Netバージョンによっては、そのままではShift-JISコードが使えないので注意。
ReadAllTextAsync
非同期読み込みバージョン。こちらのほうが早いっぽい。

使う場合には、awaitを入れないと終わっている保障がないので注意。
public async Task SimpleReadAsync() { string filePath = "simple.txt"; string text = await File.ReadAllTextAsync(filePath); Console.WriteLine(text); }
public async Task SimpleParallelWriteAsync() { string folder = Directory.CreateDirectory("tempfolder").Name; IList<Task> writeTaskList = new List<Task>(); for (int index = 11; index <= 20; ++ index) { string fileName = $"file-{index:00}.txt"; string filePath = $"{folder}/{fileName}"; string text = $"In file {index}{Environment.NewLine}"; writeTaskList.Add(File.WriteAllTextAsync(filePath, text)); } await Task.WhenAll(writeTaskList); }
基本はAsyncを使おうかと思います。
引数に、CancellationTokenというのがあります。CancellationTokenSourceオブジェクトsourceのsource.Tokenメンバーで、source.tokenを渡して始めたタスクで、source.Cancel()を呼ぶと、source.Tokenを持つタスクがTaskCanceledException例外を出すようです。むむむ・・・例外処理って基本ですが鬼門ですね。

ReadAllLines
ReadAllTextと同じくReadAllLinesAsyncがあります。stringの配列を返します。ドキュメントではLineの区切り記号は明示されていなかった??

ReadLines
Asyncはありません。(ドキュメントには・・・。ネットを見ると記述はあるので謎)
違いは、すべてのLinesを読み込みしていなくても、読み込み済みの部分にアクセス可能なので、長大ファイルの読み込みに便利とのこと。
ReadAllBytes
Asyncバージョンがあります。Text以外のものを読んでStringではなくByte[]が返り値。
コメント