C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: csvデータの1行目を削除したデータを作成する


(過去ログ 170 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■97854 / inTopicNo.1)  csvデータの1行目を削除したデータを作成する
  
□投稿者/ ひで (1回)-(2021/07/28(Wed) 22:53:18)

分類:[VB.NET/VB2005 以降] 

10GBぐらいのサイズのcsvのテキストデータの先頭行(タイトル)を1行削除したデータを作成したいのです
多きなサイズなのでテキストデータ全体をメモリに取り込んで1行削って出力するのは
メモリが大量に必要ですし
かといって1行づつ読み込み書き込みを繰り返していたら処理時間が掛かります
上記のような処理を大量メモリを消費せず高速に処理するにはどのようにするのがよいか
アドバイスいただけませんか

引用返信 編集キー/
■97855 / inTopicNo.2)  Re[1]: csvデータの1行目を削除したデータを作成する
□投稿者/ WebSurfer (2305回)-(2021/07/29(Thu) 00:27:09)
No97854 (ひで さん) に返信

> 10GBぐらいのサイズのcsvのテキストデータの先頭行(タイトル)を1行削除したデータを作成したいのです

その「1行削除したデータ」というのは何なのでしょう?

CSV ファイルというのはテキストファイルのはずですが、テキストファイルの一行だけを
削除して新たに別のテキストファイルを作るという話ですか?
引用返信 編集キー/
■97856 / inTopicNo.3)  Re[2]: csvデータの1行目を削除したデータを作成する
□投稿者/ ひで (2回)-(2021/07/29(Thu) 05:21:36)

>>10GBぐらいのサイズのcsvのテキストデータの先頭行(タイトル)を1行削除したデータを作成したいのです
>
> その「1行削除したデータ」というのは何なのでしょう?

大量のデータを1回の処理でダウンロードしきれないので
複数にファイルに分割ダウンロードしています
その分割ダウンロードしたいファイルを1つのファイルに結合したいのですが
分割ダウンロードしたcsvファイルには1行目に項目名があるのでそれを削ってから
結合しないと項目名がついたまま結合されてしまうので削りたいのです

項目名(タイトル)を削らないで分割ダウンロードしたcsvファイルをそのまま結合すると
以下のようになってしまうので、結合前に1行目を削りたいのです

項目名
データ
データ
項目名←ここを削除したい
デー多
データ
項目名←ここを削除したい
データ
データ
引用返信 編集キー/
■97857 / inTopicNo.4)  Re[3]: csvデータの1行目を削除したデータを作成する
□投稿者/ WebSurfer (2306回)-(2021/07/29(Thu) 08:39:54)
No97856 (ひで さん) に返信

> 項目名(タイトル)を削らないで分割ダウンロードしたcsvファイルをそのまま結合すると
> 以下のようになってしまうので、結合前に1行目を削りたいのです
>
> 項目名
> データ
> データ
> 項目名←ここを削除したい
> デー多
> データ
> 項目名←ここを削除したい
> データ

分割ダウンロードした複数の CSV ファイルそれぞれののサイズが「10GBぐらい」なのですか?
引用返信 編集キー/
■97858 / inTopicNo.5)  Re[3]: csvデータの1行目を削除したデータを作成する
□投稿者/ furu (123回)-(2021/07/29(Thu) 09:46:13)
2021/07/29(Thu) 10:00:31 編集(投稿者)

No97856 (ひで さん) に返信
> 項目名(タイトル)を削らないで分割ダウンロードしたcsvファイルをそのまま結合すると
> 以下のようになってしまうので、結合前に1行目を削りたいのです
大きめのバイト配列を用意し、バイナリでRead,Write繰り返すと早いです。

  System.IO.FileStream.Read(Byte[], Int32, Int32)
  System.IO.FileStream.Write(Byte[], Int32, Int32)

項目名(タイトル)のバイト数は1ファイル目を読み込んだ時にわかるので
2ファイル目からは最初のブロック読み込み時だけ
項目名(タイトル)のバイト数だけ読み取り開始位置を変えるようにします。

使ったことがありませんが、Spanを使ったほうが今どきなのかも

  System.IO.FileStream.Read(Span<Byte>)
  System.IO.FileStream.Write(ReadOnlySpan<Byte>)
引用返信 編集キー/
■97859 / inTopicNo.6)  Re[4]: csvデータの1行目を削除したデータを作成する
□投稿者/ 774RR (867回)-(2021/07/29(Thu) 13:00:09)
CSV ってことはフツーにテキストファイルのはずなので、やるべきことは1行読み飛ばすだけ
ならば自作するまでもなくて cygwin/WSL2 の head とか tail とか awk とか使うだけっス。
シェルスクリプトワンライナーで実装できる
$ rm -f cat.csv; for i in *.csv; do tail -n +2 $i >> cat.csv; done

powershell でもできそうな気がするし、自分で作っても System.IO.StreamReader / StreamWriter 使うだけ。

1行読むのにギガバイト読む必要はないので、除去だけなら一瞬だし
結合してギガバイトになったのなら遅いのはしょうがないし
何を悩んでいるのか微妙にわからん・・・

引用返信 編集キー/
■97860 / inTopicNo.7)  Re[5]: csvデータの1行目を削除したデータを作成する
□投稿者/ 古谷 (1回)-(2021/07/29(Thu) 13:35:52)
CSVのパースが遅いと仮定したときに高速に処理する方法を聞いてるんだと思った

検討課題は2つかな
・CSVのヘッダのパースをどうするか
・ヘッダ以外のコピーをどうするか

>・CSVのヘッダのパースをどうするか
ヘッダのフィールドに改行文字が入ることはないという前提が成り立つならStreamReaderで1行読めばOK
最速を目指すならStreamでbyte[]を読み取って0x0Aを探すのが良い

ヘッダーのフィールドに改行文字が入ってもよいように作るなら
CsvHelperなどのライブラリを使うか、独自にパースするか

>・ヘッダ以外のコピーをどうするか
バイナリをコピーするのが最速、StreamReaderではバイナリの読み取りができなさそう
デコード/エンコードの処理が入ることにはなるけれどもchar[]で読み書きすれば
CSVをパースするよりも2,3倍程度は速いはず

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -