- - PR -
複数の文字コードが混在したテキストファイルの操作
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-08-24 16:39
とあるパッケージソフトが作るログファイルを整形するプログラムをVB2005で作成
しようとしています(整形したファイルはDBに取り込みます)。 今回のログファイルはテキスト形式なのですが、複数の文字コードを含んでいるため、 何も考えずにファイルを開くと読めないデータが出てしまいます。 ※ログファイルはテキスト形式で、大体以下のようなフォーマットです。 -(1)---(2)-------------(3)-----------------(4)------(5)---(6)----(7)-----(8)-- ABCDE FGHIJ [01/Jan/1900:00:00:00 0900] "KLM NOP" "QRSTU" [0] [VWXYZ] 'AAAAA' BCDEF GHIJK [01/Jan/1900:01:00:00 0900] "LMN OPQ" "RSTUV" [1] [WXYZA] 'BBBBB' CDEFG HIJKL [01/Jan/1900:02:00:00 0900] "MNO PQR" "STUVW" [2] [XYZAB] 'CCCCC' ------------------------------------------------------------------------------ ※ここで(4)フィールドにUTF8、(5)フィールドにShift_JISのデータが使われています。 普通にUTF8だけで考えるなら、 Dim logReader As New System.IO.StreamReader("C:\logfile.txt", System.Text.Encoding.UTF8) Dim strLine as String = String.Empty While (logReader.Peek() >= 0) strLine = logReader.ReadLine() ....ゴニョゴニョ End While logReader.Close() なんて処理でループを回せば良いと思うのですが、文字コードが混在するケースでは どのようにファイルを扱うのが良いのでしょうか? System.IO.FileStreamでバイナリファイルとして扱おうとすると整形のロジックが 複雑になりそうな気がして、悩んでおります。。。。 [ メッセージ編集済み 編集者: Cozy 編集日時 2007-08-24 16:41 ] [ メッセージ編集済み 編集者: Cozy 編集日時 2007-08-24 16:43 ] | ||||||||
|
投稿日時: 2007-08-24 17:11
整形ロジックが複雑になるの意味がよくわからないのですが、バイナリとして読み取った後にエンコード処理を考えることでしょうか? 私は StreamReader で読み出す段階で何とかする方が複雑になると思っているのですが。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2007-08-24 17:44
どちらの文字コードで読んだ場合も表としての形はくずれないのならUTF8とShift_JISで2回読むのはどうでしょうか?
| ||||||||
|
投稿日時: 2007-08-24 18:53
返答ありがとうございます。
テキストファイルをバイナリとして扱う際の流れ(お作法)が分かっていないので、「行」の切り出し 方法や、エンコード処理の考え方がイメージ出来ません。 今回のログファイルはデリミタである空白文字が随所で出てくるため、各フィールドを括っている"[]' の文字列を利用しながらフィールド区切りを扱う必要があるので、よけいに頭が混乱しています。
処理やリソースが2倍必要になるのが悩ましいところです。 | ||||||||
|
投稿日時: 2007-08-24 19:47
N×N回の処理になっちゃうなら嫌ですが単に2倍になるだけなら気にならないこともありますよ。 ログファイルの大きさにもよりますね。どのくらいなんですか?あとファイルの数も。 絶えずこの処理が回り続けるとかなら少しでも軽い方がいいですけどね。 | ||||||||
|
投稿日時: 2007-08-25 12:50
バイナリデータの扱いって地道に1バイトずつチェックするだけですよ。 1バイトずつデータをチェックして、 フィールドと行末を判断すればよいですよね。 1行は改行コード(CR+LFですか?)が出てくるまでですよね。 1フィールドはどのように規定されているのか、提示のログの例からでは 確実なことはわかりませんが、1バイトずつチェックして各フィールドに ばらす方法を検討しましょう。
ログの例を見る限りでは、 1. フィールドの区切りは1つの空白 2. 各フィールドは[]、""、''などで括られている場合がある といったルールのように見えます。 (空白が出てきたら基本的にはフィールドの区切りだが、 []、""、''などの中の空白はフィールドデータの一部といった ルールもあるのでしょう) こういったルールだとして、 1バイトずつチェックする中で、空白、[、]、"、'、その他のデータを 文字コードで区別して、それぞれに応じた処理をすればよいですね。 | ||||||||
|
投稿日時: 2007-08-25 13:16
シフトJISの2バイト目は、例えば [ (0x5B) や ] (0x5D)と同じになることがあるので注意してくださいね。
UTF-8はどうなんってんだろうなあ。 | ||||||||
|
投稿日時: 2007-08-25 16:12
私の処理手順では、2バイト以上の文字への考慮が抜けてました。 フォローありがとうございます。ちょっと調べてみました。 UTF-8 http://ja.wikipedia.org/wiki/UTF-8 のエンコード体系を見ると1バイト目を見れば、何バイトで構成されているかは判断できるようです。 Shift_JIS http://ja.wikipedia.org/wiki/Shift_JIS によれば、第1バイトが0x81〜0x9Fならびに0xE0〜0xFCとのことなので、 UTF-8の3バイト以上の文字とは第1バイトがかぶっているようですね。 また、Shift_JISとUTF-8が混在するとなると Shift_JISとUTF-8のどちらか判断するには何バイトか先読みが必要になりそうです。 例えば、 0xE0 0x80 0x7f のようなデータの並びだと2バイト目まで読んだ状態では、 Shift_JISかUTF-8か判断できず、 0x7fが登場した時点で初めてShift_JISと判定できますね。 例えば、UTF-8の3バイト文字が使われることがないとか 条件を限定できればいいですが、そうでないと結構面倒そうですね。 |