@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

改行コードを含んだCSVファイルの読み込みについて

投稿者投稿内容
バニラミント
ベテラン
会議室デビュー日: 2005/05/27
投稿数: 58
投稿日時: 2006-07-14 19:24

CSVファイルの入出力を作成しています
CSVファイルの最初の行にヘッダを記述しているので
1行読み飛ばして、ループの最初で、文字列をsplitで分割し
配列にいれてから、INSERT文を文字列で生成し、DBへ
登録しようと考えています。

テストの時には問題はなかったのですが、実際のデータで
試験中に読み込めないデータがあり、調べてみると、
1レコード分のデータの途中に改行コードが
入っているものがあることがわかりました。

ReadLineで1行読んだ際に、途中に改行があるため
正常に読み込めません。
テキストエディタで途中の改行を除去すれば、正しく読めます。
1回限りの読み込みなら、エディタで直そうかと思ったのですが
処理の都合上、改行入りのデータを毎日読む必要があります。
さすがに毎日エディタで直すわけにもいかなく・・・

なんとか途中の改行を回避して読み込む方法はないものでしょうか?

バイナリエディタで見たところ、途中の改行も、1レコード最後の改行も
同じ「0D」でした。

【開発環境】
WindowsXP Pro
VisualStudio2003 VB.NET


以下ソースです。
-----------------------------------------------------------

Dim sr As New System.IO.StreamReader(.FileName, System.Text.Encoding.Default)

'1行ずつ読み込み
Dim strLine As String = sr.ReadLine
strLine = sr.ReadLine ' 1行読み飛ばし

While Not strLine Is Nothing

Dim impDAT() As String = strLine.Split(",")

If impDAT.Length = 32 Then

Dim imp As New dt_av

imp.field01 = impDAT(0).Replace("""", "")
imp.field02 = impDAT(1).Replace("""", "")
imp.field03 = impDAT(2).Replace("""", "")

中略・・・・・・・
きくちゃん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 854
お住まい・勤務地: 都内某所
投稿日時: 2006-07-14 19:53
バニラミントさん、こんばんは。

引用:

1レコード分のデータの途中に改行コードが
入っているものがあることがわかりました。


それは CSV として NG なので、出力側を何とかすべきだと思います。

どうしても取込側で何とかする必要があるのなら、Split で得られた配列の Length を見て、規定数に達していなければ次の行も含めてやれば良いと思います。
ぽぴ王子
ぬし
会議室デビュー日: 2006/03/24
投稿数: 475
お住まい・勤務地: お住まい:城・勤務地:城
投稿日時: 2006-07-14 20:09
こんばんは。

引用:

きくちゃんさんの書き込み (2006-07-14 19:53) より:

それは CSV として NG なので、出力側を何とかすべきだと思います。


個人的にはこの意見に激しく同意したいところなのですが、たぶんにそうもいかないと思
いますので(笑)なんとかするしかないのかなと。

引用:

バニラミントさんの書き込み (2006-07-14 19:24) より:

バイナリエディタで見たところ、途中の改行も、1レコード最後の改行も
同じ「0D」でした。



ここは少し調査が必要だと思います。一般的に Windows で作られたテキストファイル
は \r\n(0D 0A)が改行コードになると思われます。
もしかして Macintosh (しかも OS9 )で作られたファイルだったりしますでしょうか?
StreamReader.ReadLine のヘルプを読むと、\n または \r\n を改行とみなすようで
すので、本当に改行が 0D(\r)ならば途中改行どころか正常な改行も認識できないよ
うな気がします。
ちなみに手元の Excel で途中改行の入った CSV ファイルを作成してみたところ、行末
は \r\n 途中改行は \n というデータが作成されました。

Excel が出力した CSV と同じタイプのファイルだと仮定して、それでは
StreamReader.ReadLine は途中改行を行末として認識してしまうためにそのままで
は利用できません。
その場合どうするかと言うと、バイナリファイルとして読み込んで、自力で \r\n までを文
字列として整形してから途中の \n を削除などするかなぁ(自分なら)と思います。

あと見ていて気になったのですが
>imp.field01 = impDAT(0).Replace("""", "")
>imp.field02 = impDAT(1).Replace("""", "")
>imp.field03 = impDAT(2).Replace("""", "")
これちょっと見直そうぜ。な!(ぶさいくろうさん風に)
_________________
ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2006-07-14 20:47
私は、Excel の出力した CSV なんかは一行の中に改行が入っている場合があるので、行の中のダブルクォーテーションを数えて、奇数個だったら、次の行も読んでくっつけちゃいます。
#もちろん、それでも奇数個だったら、さらにつなげます。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-07-14 21:20
Excelが吐くCSVは、データの中に、

・改行・ダブルクォーテーション・カンマが含まれればダブルクォーテーションで囲む
・ダブルクォーテーションはダブルクォーテーションを2つにエスケープする

って感じのルールっぽいです。(正式な仕様は知りませんが)

どういう環境で作られたCSVかは知りませんが、
入力側は出力されるCSVの仕様にあわせて作る必要がありますね。
データ交換のに使われるデータのフォーマットというのは、
XMLのように正式な仕様があれば問題ありませんが、
CSVのようにオレオレ仕様があるものに関しては、
入力・出力側それぞれが仕様を統一すべきでしょう。
R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-15 09:16
>改行コードを含んだCSVファイル

これは CSVファイルと言わない希ガス・・・
TABで区切ったCSVファイルとか、固定バイト長で区切ったCSVファイルみたいなw

僕は、テキストファイルからインポートする処理をする場合は、最初のインポート元のファイルが正常かどうかを見るようにしています。
その時、ついでに改行コードとフィールド区切りを次の手順で探します。

レコード分離処理
(以下、2件以上になればレコード分離終了)
(1) CRLFで区切る
(2) CRで区切る。
(3) LFで区切る。

フィード分離処理
(1) "," で区切る。
(2) , で区切る。
(3) "tab" で区切る。
(3) tab で区切る。

で区切った場合のフィールドの数を数えて、これに満たなければ次の行から持ってきます。
で、数がぴったりにならない場合はインポートエラー。
これを使いまわしていますが、フィールド数が一定でない場合は使えないです。
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2006-07-15 09:49
改行コードを含んだ CSV って、なんか拒絶反応を起こす人多いんですね。

私なんかは、Excel の CSV 出力がそういう感じなんで、いつもそれを基準にしています。
仕様書にも、平気で Microsoft Excel と同様の出力形式って書きますしね。

それは、さておき、田中さんのフィールド分離方式がまずいので、ちょっとフォロー。

例えば、"a","b",c っていう行があると、("a),(b"),(c) という感じで変になってしまうかと。

私は、

ダブルクォートが0個:そのままカンマで split
ダブルクォートが奇数個:次の行も改行コードをつけて連結
ダブルクォートが偶数個:カンマとダブルクォートを前から一項目ずつ解析

って、やっています。

もうちょっといい手があったら、私も教えて欲しいですが。



R・田中一郎
ぬし
会議室デビュー日: 2005/11/03
投稿数: 979
投稿日時: 2006-07-15 11:22
引用:

わちゃさんの書き込み (2006-07-15 09:49) より:

それは、さておき、田中さんのフィールド分離方式がまずいので、ちょっとフォロー。

例えば、"a","b",c っていう行があると、("a),(b"),(c) という感じで変になってしまうかと。


おおっ、確かに!
数値は、"" なしってパターンありますからね。
以前書いて、うろ覚えのまま投稿してしまったもんで、フォローありがとうございます

今確認したら、分離した後に、両端を調べて " ' の順で両方括られていたら外すって処理をしていました。

スキルアップ/キャリアアップ(JOB@IT)