質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

20736閲覧

C# シフトJISのCSVデータをUTF-8に変換する方法。

GiveAHand

総合スコア286

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2016/06/05 12:00

編集2016/06/05 12:41

いつも大変お世話になっております。

C#でCSVからデータを読み込んで、SQLiteに書き込むというプログラムを作成しています。

CSVはSJISでSQliteはUTF-8なので、読み込んだデータをUTF-8に変換しなければいけないのですが、それがうまくいきません。

データは、まず、webcliantでFTP接続をして、このようにダウンロードをしています。

C#

1// バイナリを文字列に変換(UTF8 -> 文字列) 2string str = System.Text.Encoding.UTF8.GetString(sourceData, 0, sourceData.Length); 3 4// StreamWriter の作成 5using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@item.filepath, false, System.Text.Encoding.GetEncoding("shift_jis"))) 6{ 7 // ファイルへの書き込み(このとき文字列 -> Shift-JIS) 8 sw.Write(str); 9}

そのようなデータを、以下のように、StreamReaderを使って読み込んでいます。

C#

1// csvファイルを開く 2using (var sr = new System.IO.StreamReader(@csvfile.filepath)) 3{ 4 5 // ストリームの末尾まで繰り返す 6 while (!sr.EndOfStream) 7 { 8 // ファイルから一行読み込む 9 var line = sr.ReadLine(); 10 } 11 12}

このように読み込んだデータを、

http://dobon.net/vb/dotnet/string/getencoding.html

このページにあるように、

C#

1bytesData = System.Text.Encoding.UTF8.GetBytes(value); 2cmd.Parameters["data"].Value = System.Text.Encoding.UTF8.GetString(bytesData);

このようにして、UTF-8に変換しようとしているのですが、これではうまくいきません。

というか、そもそも文字コード変換は、
デコードやエンコードと共にしか出来ないのでしょうか?

もしくは、ReadLineメソッド実行時にエンコードさせる方法は無いでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

文字列としてsqliteに保存すれば自動的にエンコードはなされますが、それではいけないのでしょうか?

投稿2016/06/05 12:14

Zuishin

総合スコア28662

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

GiveAHand

2016/06/05 12:17

Zuishin様 そうなんですか? 実際にセットされたデータは文字化けしてしまっているのですが、 では、一体原因は何なのでしょう?? つまり、シフトJISの文字コードのCSVでも、 普通に読み込んで、普通にセットすればいいという事なんですよね?
Zuishin

2016/06/05 12:28

どのように保存し、どのように取り出し、どのように表示しているか教えてください。 表示の部分で化けているのかもしれません。 シフトJISで書かれたテキストも、適切なエンコードで読み取ってstring型にしている時点でシフトJISではなくなります。 挙げられたソースの場合、ReadLine()で得られる文字列はシフトJISではありません。
GiveAHand

2016/06/05 12:43

Zuishin様 今、説明に追記させて頂きましたが、CSVファイル自体は、サーバーにwebclientで接続し、UTF-8をSHift-Jisに変換してダウンロードしています。 // バイナリを文字列に変換(UTF8 -> 文字列) string str = System.Text.Encoding.UTF8.GetString(sourceData, 0, sourceData.Length); // StreamWriter の作成 using (System.IO.StreamWriter sw = new System.IO.StreamWriter(@item.filepath, false, System.Text.Encoding.GetEncoding("shift_jis"))) { // ファイルへの書き込み(このとき文字列 -> Shift-JIS) sw.Write(str); } この部分は、少なくともテキストエディタで開くと、文字化けせずに見れるので、うまくいっているように見えます。
Zuishin

2016/06/05 13:00

ファイルへの保存までの説明ありがとうございます。 この時点でシフトJISで保存されています。 しかし、これをReadLine()で読み込まれた時点でシフトJISではなくなり、UTF16になります。 実際には、UTF16であることは意識する必要もなく「string型」というエンコード無関係の新たなデータと理解される方が良いかもしれません。 文字化けが起こるのは、次にsqliteへ保存する時点、そこから取り出す時点、表示する時点の三か所が考えられますので、そこのところをお聞きしたかったところですが、おそらく問題は保存する時点にあると思っています。 通常、sqliteのテーブルを作る際に、文字列を保存するフィールドはTEXT型にします。そしてTEXT型のフィールドにstringを保存すると、自動的にUTF8にエンコードされます。 ですので、文字化けするとすれば、stringを書き込むべきTEXT型のフィールドにバイト文字列を書き込んでいるからではないかと推測しています。 いかがでしょうか?
Zuishin

2016/06/05 13:26

蛇足ながらもう一点。 シフトJISのファイルから読み込まれる際にエンコードの指定なしに正しく読み込めるのは日本語版Windowsのみです。 読み込み部分を次のように変更されることをお勧めします。 foreach (string line in File.ReadLines(csvfile.filepath, Encoding.GetEncoding("Shift_JIS")) { // 処理 }
GiveAHand

2016/06/05 13:47

Zuishin様 いろいろとご丁寧にありがとうございます。 var line = sr.ReadLine(); で読み込んだデータは、 var values = line.Split(','); でカンマ区切りにし、その後、 foreach (var value in values) { } でループさせたものをセットしてます。 この場合は、valueは、バイト文字という事になるのでしょうか? valueをstringに変換しなければいけないという事なのでしょうか?
GiveAHand

2016/06/05 13:48

>foreach (string line in File.ReadLines(csvfile.filepath, Encoding.GetEncoding("Shift_JIS")) { >// 処理 >} こちらの件、ありがとうございます。 やってみます。
Zuishin

2016/06/05 13:53

string.Split()で得られるvalueはstringです。 戻り値の型はマウスを当てると確認できますよ。 バイト文字列という表現を使いましたが、誤解を招きそうなのでバイト配列に言い直します。GetBytes()で得られるのがバイト配列です。 文字列(string)をバイト配列に変換するのをエンコード、その逆をデコードと言います。 ReadLine()によって自動的にデコードされてstringになります。 sqliteのTEXTフィールドへはstringを書き込めば結構です。 エンコードは自動的に行われるので、こちらがする必要はありません。
GiveAHand

2016/06/05 13:57

Zuishin様 といいますか、プログラムを見ますと、ReadLine()で読み込んだ時点の文字列をコンソールに出すと文字化けしています。 という事は、やっぱり読み込み時に文字化けしてしまっている気がするのですが、どうなのでしょう。。。 ちなみにCSVはテキストエディタで見ても、エクセルで開いても文字化けはしていなので、それは問題ないと思うんです。。。
Zuishin

2016/06/05 14:15

ではデフォルトのエンコードがシフトJISになっていないんでしょう。 私の書いた方法で読み込んでみてください。
Zuishin

2016/06/05 14:17

失礼しました。 ファイル自体が文字化けしています。 StreamWriterはstringを書き込むものです。GetByte()は使わないでください。
GiveAHand

2016/06/05 14:25

Zuishin様 読み込み時に、 >foreach (string line in File.ReadLines(csvfile.filepath, Encoding.GetEncoding("Shift_JIS")) { >// 処理 >} とはちょっと違うのですが、 using (var sr = new System.IO.StreamReader(@csvfile.filepath, System.Text.Encoding.GetEncoding("shift_jis"))) { ここで、Shift_Jisの指定をする事によりうまくいきました! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問