
Microsoft Visual Studio Community 2022 (64 ビット) - Current Version 17.5.5
のC#で大量のCSVファイルのデータを読み込んでそれを
WindowsフォームアプリではtextBoxにAppendTextで追加する方法と
コンソールアプリではConsole.WriteLineで追加する方法では、
表示速度がWindowsフォームアプリの方が圧倒的に遅いのですが
これは何が原因なのでしょうか?
またWindowsフォームアプリでこの処理を早くするにはどうすれば良いのでしょうか?
【コンソールアプリ】
public class Program
{
static void Main(string[] args)
{
TextFieldParser parser = new TextFieldParser("USDJPY.csv", System.Text.Encoding.GetEncoding("Shift_JIS"));
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(",");
parser.ReadLine();
int cnt = 0;
DateTime dt_start = DateTime.Parse("2022-12-29 00:00:00");
DateTime dt_end = DateTime.Parse("2022-12-30 23:59:00");
while (parser.EndOfData == false)
{
string[] column = parser.ReadFields();
DateTime dt = DateTime.Parse(
column[0].Substring(0, 4) + "-" +
String.Format("{0:D2}", column[0].Substring(5, 2)) + "-" +
String.Format("{0:D2}", column[0].Substring(8, 2)) + " " +
String.Format("{0:D2}", column[1].Substring(0, 2)) + ":" +
String.Format("{0:D2}", column[1].Substring(3, 2)) + ":00");
Console.WriteLine(column[0]);
if (dt < dt_start) continue;
if (dt > dt_end) continue;
Console.WriteLine("■"+column[0]);
}
}
}
【Windowsフォームアプリ】
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void readCSV()
{
TextFieldParser parser = new TextFieldParser("USDJPY.csv", System.Text.Encoding.GetEncoding("Shift_JIS"));
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(",");
parser.ReadLine();
int cnt = 0;
DateTime dt_start = DateTime.Parse("2022-12-29 00:00:00");
DateTime dt_end = DateTime.Parse("2022-12-30 23:59:00");
while (parser.EndOfData == false)
{
string[] column = parser.ReadFields();
DateTime dt = DateTime.Parse(
column[0].Substring(0, 4) + "-" +
String.Format("{0:D2}", column[0].Substring(5, 2)) + "-" +
String.Format("{0:D2}", column[0].Substring(8, 2)) + " " +
String.Format("{0:D2}", column[1].Substring(0, 2)) + ":" +
String.Format("{0:D2}", column[1].Substring(3, 2)) + ":00");
textBox1.AppendText(column[0]+Environment.NewLine);
if (dt < dt_start) continue;
if (dt > dt_end) continue;
textBox1.AppendText("■" + column[0] + Environment.NewLine);
}
}
private void button1_Click(object sender, EventArgs e)
{
readCSV();
}
}
No.7ベストアンサー
- 回答日時:
説明の仕方が悪かったですね。
申し訳ありません。通常であれば、マルチスレッドのプログラミングをする場合、各スレッドから、同じ変数にアクセスする可能性がある場合は、排他制御を行うべきです。
つまり、rowは、readCSV()とbutton1_Click()から同時アクセスされる可能性があったので、Button1をdisableにしておけば、button1_Click()が呼び出されることもなく、修正が少なくて済むだろうと単純な考えでの提案でした。
なので訂正させてください。
buttonのdisablleはやめて、フォームload時に、セマフォを初期値0、最大値1で作成し、readCSV()を抜けるときに、セマフォをRelese()してください。
button1_Click()内で、enable/disableのチェック代わりに、WaitOne(0)で呼び出し、戻り値がfalseであれば、読み込みが終わってない状態なので、何もせず、trueであれば、処理を行うようにしてください。
https://learn.microsoft.com/ja-jp/dotnet/api/sys …
ボタンがdisableにはなりませんが、そこはmessageboxを表示するなり別途考えていただくということで、お願いします。
と、説明させていただきましたが。。。
結局、readCSV()がパフォーマンスに、影響がないということが、今回のテストで確認できたので、質問者さんが一番最初に作った670万回ループを、少し変更し、AppendText()部分だけど、今回の1000回に1回書き込むループに変更すれば、メモリのエラーもなくなり、パフォーマンスも劇的に向上するのではないかと思われます。
全体を読み込むのに、1分程度で、読み込めるのではないでしょうか?
つまり、threadも、semaphoreはもちろん、rowsや、button1のenabl/disableも必要なくなるわけです。
ご返信ありがとうございます。
たしかにreadCSV()ってそんなに時間がかかってなかったです。
自分はプロセスメモリを見て増えるのが止まったらbutton1を押してました。
1000回に1回書き込めば速度が速くなるのですが、ただやはり1行づつ見たいというのがありまして
コンソールアプリで表示させようか迷ってます・・・
ただそのVisual StudioのプロジェクトがメインがWindows フォームアプリなので
そこではコンソールフォームがどうやっても出てこないんです。。
この問題についはまた新たに別に質問を立てたいと思います。
この度はありがとうございました。
No.6
- 回答日時:
アップロードありがとうございます
ソースコード拝見させていただきました。これで差分がほとんどないということは、AppendText()がほとんどのネックですね
今は、readCSV()のスレッドは、すぐに終わってるようなので、問題無いですが、rowsに対するの排他制御がないので、readCSV()が終わる前にボタンが押されると、デッドロックを起こしたり、全ての行を読み込む前に、foreachを抜ける可能性があると思うので、button1がクリックされる前に、ブロックする必要はあると思います(簡単なのは、bottun1は起動時は、disableで、readCSV()が終わる前に、bottun1をenableにするとか)
かなり気になるのが、質問者さんに実行していただいた1万行のテストパフォーマンスから単純計算すると、2.4時間で読み込みが完了するはずですが、実測で半日かかるということは、TextBoxサイズが肥大化していくと、極端にパフォーマンスが悪なる現象が起きてるのではないかと、推測できます
それを考えると、TextBoxに全てのデータをロードする、その設計自体を根本的に見直す必要があるのではと思います
と思って、調べてみるとありました。
https://www.ipentec.com/document/csharp-textbox- …
このサンプルをヒントにすると、foreach内のAppendTextをやめて、そこでは、単一のstringを構築する方法に変更にして(改行コードも追加し)ループを抜けたあとに、構築した単一のstringをAppendTextで追加するとどうなのか?それで、かなりのパフォーマンス改善が得られるのでは?と思いますが、どうでしょうか?
ご返信ありがとうございます。
こちらの都合でまた返信が遅れるかもしれませんがよろしくお願いいたします。
すみません、半日かかると書きましたが
だいぶ前に実行して試した時の記憶だったので、そんなにかかってなかったかもしれません(汗)
とにかく凄い時間がかかったというのはたしかです。
なるほど、AppendTextのネックですか。
そこでcntをインクリメントして
一定の回数ごとに(その時の)行の内容を情報をAppendTextに渡す方法で670行でのデータで試してみたのですが、
cnt%1000 == 0 処理時間:処理時間:8.20 秒
と劇的に早くなりました。
つまりこれは単純に計算して処理時間が1000分の1になったということですよね?
(ちなみに全ての行を表示させようとするとメモリのエラーが出るようです・・・添付画像を参照してください)
https://s.kota2.net/1683534766.png
ただ、そもそもTextBoxを利用しようとした目的が1行づつの進捗状況が見たかったからなので
やはりどうにかして1件1件が追加されたという情報を逐次、何かで知ることはできないでしょうか?
あとbottun1のdisable、enableの判定ですが、
readCSV()内で終わりにbutton1.Enabled = true;を追加すると
System.InvalidOperationException
HResult=0x80131509
Message=有効ではないスレッド間の操作: コントロールが作成されたスレッド以外のスレッドからコントロール 'button1' がアクセスされました。
というエラーがでます・・・
なのでisLoadedCSVという判定変数を用いてなんとかできないか考えてるのですが、
isLoadedCSV == trueならbutton1.Enabled = trueにする処理をどこで記述すれば良いのでしょうか?
https://ux.getuploader.com/dialogues_txt/downloa …
No.5
- 回答日時:
今の状況を整理すると
67万行を一度に読み込むと、予測では14分程度待つ必要があるので、許容できないという前提で、それを解決できる方法を検討してると理解しています。
判明してることは、AppendText()をループで回すと、処理に時間がかかるので、1)ApendText()に変わる良い方法はあるのか?が一つ、2)ApendText()を使った場合どうやって解決すればいいか?がもうひとつ
自分からは、2)のApendText()を一度に呼ばない方法をメインで提案しています。
少し頭を冷やして、ApendText()を分割する方法をいくつか検討してみました
1)ボタン追加で、500件ごと読み込む方法
UIに、追加のボタンが許容できるのであれば「次の500件を読み込む」「前の500件に戻る」ボタンをUIに追加し、今のreadCSV()を、setupCSV()と、readCSV()に分割し、parserはフィールドに、また、while文をfor分に変更し、break条件を、EODか500までカウントアップする方法に変更します。ただし「前の500件に戻る」ボタンをつけることで、TextFieldParserでは遡っての、再読読み込みは実現が難しいので、ページ毎のTextBoxオブジェクトを1340個を持つ必要性と、どのページを表示しているか、enable/disableのコントロールや、既に読み込んだページと、これから読み込むページなどの管理が必要になります。
2)ファイルの一括読み込みと、ApendText()を分ける方法
プログラム起動時に、別スレッドでcsvファイルメモリ上に読み込み、parserを通した、stringオブジェクトを67万行分キープします(30Mbyte弱ほどになる予想)。ボタン1が押された場合には、AppendText()のみを実行し登録。予測ではAppendText()のみを67万回実行するのであれば、4分ぐらいで終わるのではと思っています。4分が許容できるかどうかですが。。。
3)スクロールバーのイベントから次の500ラインを読み込む方法
これが一番メモリへの影響などのインパクトが薄いですが、インプリメントや変更は多いと思います。ボタン1が押された後に、ファイルを分割して読み込む方法で、今の、readCSV()を分割して、setupCSV()とreadCSV()に分割します。readCSV()のwhile文をfor文に変えて、breakする条件を、EODか、500までのカウントアップに変更し条件に一致すれば終了します。
それと共に、TextBoxのVScrollbarのScrollイベントで、SB_BOTTOMを検出したら、次の500ラインを読み込む。としていけば、ストレスがなく、読み込めるのではないかと思ってます。EODが検出されれば、readCSV()は、実行しなくても良いので、より、高速になると思います。
これが参考になるかとは思います。
https://www.ipentec.com/document/csharp-detect-s …
どの方法が適しているかは、なんとも言えませんが、これ以外にも、まだ解決方法があるとは思います。
もし、これらの方法が難しいと考えるのであれば、一旦、この質問は閉じていただいて、他の方の意見を伺うために、67万行のcsvファイルをTextBoxにApendText()で追加する場合のパフォーマンスの改善できる良い方法はないか?という質問をしていただくのも手かとは思います。
念の為、500行というのは質問者さんがテスト結果から、500行だと0.6秒程度の予測なので、その程度れあれば、ほぼブロックされている感覚がないという前提の数字です。
ご返信ありがとうございます。
67万行が14分程度なら全然許容範囲です(半日ぐらいかかってましたから・・・汗)
とりあえず、ご提案があった2の方法を1万件のデータで試してみのですが、
処理時間:12.34 秒 とそんなに変わらなかったです・・・
ちょっとやり方を勘違いしている可能性があるので見てもらえないでしょうか。
文字数制限があるのでアップローダーでダウンロードをお願いします。
https://ux.getuploader.com/dialogues_txt/downloa …
No.4
- 回答日時:
測定ありがとうございます。
1万行で、ほぼ10秒の差ということは、一回の呼び出し差は1msでしかないです。
これは、APIが遅いというレベルではなく、ループ回数が多すぎるということになるので、一度に全てを読み込むのは、設計上好ましくないという判断になると思います。
対応策は、読み込みを分割するのが適切で、初期読み込みは、500行程度(今のCPUで0.6秒程度の計算)終了し、スクロールエンドに来れば、再度読み込む、といった処理にするか、スレッドを作って、残りのデータを読み込むなどの方法で、分割すべき内容かとは思います
※間違えて自分自身で「いいね」を押してしまいました。お気になさらずに。
ご返信ありがとうございます。
すみません、先ほどから「読み込みの分割」というのが
いまいちわからないのですが、
これってReadLineで
while (parser.EndOfData == false)
{
textBox_Output.AppendText(parser.ReadLine() + Environment.NewLine);
}
一行づつ読み込んでますよね?
例えばReadMultiLine()みたいな関数があったとして
一気に1万行を読み込んでいたのなら、その分割した方が良いというのはわかるのですが、
この場合ってこれ以上どうやって読み込みを分割すれば良いのでしょうか?
※おそらく自分が勘違いしてるので、このような質問になってしまうのですがすみません
No.3
- 回答日時:
元々の質問内容は「何が原因でしょうか?」ということでしたので、自分の仮説では、メモリアロケーションが要因だと思うので、SingleLineにした場合は、メモリアロケーションが発生しないと思われるので、Consoleと同程度のパフォーマンスが得られるのでは?という考えで、それを証明するために、時間計測を提案させていただきました。
つまり、
1)Console.WiteLine()と、SingleLineTextの開始から終わりまでの時間を測定すると、ほぼ、同程度で終わるのでは?と仮説
2)Console.WriteLine()を使った時に、それぞれのLine分のstringをメモリアロケーションして、コピーし計測した場合と、MultiLineTextの場合とほぼ同じ時間がかかるのでは?という仮説
で、その二つのケース測定した結果、それぞれテストの時間の差分がほぼなければ、csvファイルを一度に読み込む処理をやめて、分割してcsvファイルを読み込むという処理に変更せざるを得ないのでは?と思ってます
1000行程度読み込んで、残りはバックグラウンドで読み込むなどの設計変更が必要ではないのか?とは思っています
ご返信ありがとうございます。
ちょっとそのサイトの計測の仕方を利用して計測してみました。
さすがに76万行だと多いので1万行でそれぞれ計測した結果です。
Windowsフォームアプリ:処理時間:12.58 秒
コンソールアプリ:処理時間:2.79 秒
これからどのようなことが分かりますでしょうか?
また対処法はどうなりますか?
ちなみに文字数オーバーなので、また補足にコードの一部を載せたいのですが、
足りるかなぁ・・・
コードの一部です
【Windowsフォームアプリ】
TextFieldParser parser = new TextFieldParser("USDJPY.csv", System.Text.Encoding.GetEncoding("Shift_JIS"));
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(",");
parser.ReadLine();
long startcount;
QueryPerformanceCounter(out startcount);
while (parser.EndOfData == false)
{
textBox_Output.AppendText(parser.ReadLine() + Environment.NewLine);
}
long endcount;
QueryPerformanceCounter(out endcount);
double sec = (double)(endcount - startcount) / (double)freq;
textBox_Output.Text += string.Format("処理時間:{0:f} 秒\r\n", sec);
No.2
- 回答日時:
うわ
流石に貼られるとは、思ってなかったですw
こういうデバッグをする場合には、計測して、ボトルネックが何処か、特定する事が大事だと思いますので、まずは、処理時間を計測をした方が良いと思います。
良いサンプルがありました
https://www.ipentec.com/document/csharp-using-qu …
ご返信ありがとうございます。
すみません、そのご紹介いただいたサイトの内容もそうなのですが、
計測とのことですがどこを計測するのかが分からないというか
つまり
while (parser.EndOfData == false)
{
textBox1.AppendText(parser.ReadLine() + Environment.NewLine);
}
このループの部分が時間がかかってることは分かるのですが、
これ以上どこを分解して測れば良いかが分からないのです・・・
AppendTextの実装の部分で何が行われてるのか分かれば良いのですがどうなんでしょう。。
No.1
- 回答日時:
コードが全て見えているわけではないので、参考までに
コンソールアプリは、テキスト用のバッファーをアロケーションしません。そのため、メモリによるサイズ圧迫はないでしょう
一方で、質問者さんが使っているTextBoxはマルチラインだと思いますので、その分stringバッファを取ると思います。つまり、サイズが大きくなればなるほど、メモリのアロケーションが繰り返され、メモリを圧迫してるのではないでしょうか?
TextBoxをシングルラインにしても、同じようにパフォーマンスが落ちるのか?また、コンソールアプリの時に、テキストバッファをアロケーションした場合に、同じようにパフォーマンスが落ちるのか?
一つの判断はそこでしょうか?
メモリの圧迫であれば、タスクマネージャーを見てるだけでもわかるかもしれません
ご回答ありがとうございます。
メモリは32GBあるので大丈夫だとは思うのですがどうなんでしょうか?
TextBoxをシングルラインに戻して実行してみたのですが、
なんせ1行しか見れず高速でテキストが見えたり見えなかったりしてるので
どのくらいの速度でデータがTextBoxに入ってるかが分からないです・・・
もしよろしければよっしーラボさんの方で次コードで
Visual Studioを利用できれば試していただけないでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 日付で矢印マクロ 4 2023/07/25 16:47
- C言語・C++・C# クラスのメンバ変数を基準に並べ替えをしたい 5 2022/12/25 17:40
- PHP PHP MySql 画像を取得 1 2022/06/04 14:05
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) vb.net どうしてイコールにならないのでしょうか 4 2022/09/29 12:21
- Visual Basic(VBA) 複数csvを横に追加していくマクロについて 2 2023/04/25 09:19
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Visual Basic(VBA) Excel vbaについての質問 3 2023/04/18 16:14
このQ&Aを見た人はこんなQ&Aも見ています
-
一回も披露したことのない豆知識
あなたの「一回も披露したことのない豆知識」を教えてください。
-
【お題】動物のキャッチフレーズ
【お題】「百獣の王 ライオン」「実は動物界最強 カバ」は分かるけど、それはちょっとピンと来ないなと思った動物のキャッチフレーズ
-
人生で一番思い出に残ってる靴
皆さんの人生で一番思い入れのある靴の話を伺ってみたいです。
-
はじめての旅行はどこに行きましたか?
記憶の中で1番昔の旅行先とエピソードを教えてください。
-
あなたが好きな本屋さんを教えてください
どのくらいの規模間で、どのような本が並んでいるか、どのような雰囲気なのかなどなど...
-
C# でDataTableの更新を高速化したい。
C言語・C++・C#
-
FORMが開いているかどうかの確認方法
Visual Basic(VBA)
-
ピクチャーボックスの大きさに合わせて画像を表示
Visual Basic(VBA)
-
-
4
DataGridViewでセルクリックイベントを発生させるには
Visual Basic(VBA)
-
5
他のアプリケーションとの連携
Visual Basic(VBA)
-
6
EXCELで特定のセルに表示された項目をヘッダーやフッターに出力するには
Excel(エクセル)
-
7
VBAでエクセルシートを更新(リフレッシュ)する方法を教えて下さい。
Excel(エクセル)
-
8
Viewにインデックスは張れますか?
Oracle
-
9
VB.NETでファイル名順にファイルを読む方法
Visual Basic(VBA)
-
10
Hideについて(.NET)
Visual Basic(VBA)
-
11
データグリッドビューの一番最初の行に列を追加したい
Visual Basic(VBA)
-
12
Designer.vbは直接コードをいじってはだめ?
Visual Basic(VBA)
-
13
CSVファイルによる検索の高速化
PHP
-
14
「タイプ初期化子が例外をスローしました」エラー何?
Visual Basic(VBA)
-
15
C# シリアル通信でデータ受信時の欠損について
C言語・C++・C#
-
16
Ctrl + Cなど複数の入力キーの感知
Visual Basic(VBA)
-
17
C# dataGridViewの値だけクリア
C言語・C++・C#
-
18
DoEventsがやはり分からない
Visual Basic(VBA)
-
19
C# DataTableに最後に追加した行をDataGridView上で選択状態にする方法は?
C言語・C++・C#
-
20
C# DataGridView のヘッダーセル中央揃え
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・昔のあなたへのアドバイス
- ・字面がカッコいい英単語
- ・許せない心理テスト
- ・歩いた自慢大会
- ・「I love you」 をかっこよく翻訳してみてください
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・はじめての旅行はどこに行きましたか?
- ・準・究極の選択
- ・この人頭いいなと思ったエピソード
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Junitテストでvoid戻り値メッソ...
-
大量のデータを読み込んで表示...
-
Javaでタイマーの使い方
-
C#で、あるクラスのメンバーす...
-
C# visibleプロパティをfalseに...
-
C#から、C++で作成したdll内の...
-
C#でのDLLのメソッドの作り方
-
StrutsのiterateタグでListに格...
-
C# MouseHoverを何度も呼ぶには
-
LVM_SETITEMSTATEでListViewの...
-
C#で別のFormへ複数の値を返そ...
-
unityでのC++エラーの原因がわ...
-
JavaSwingのファンクションキー...
-
C# WinForm のDataGridView Cel...
-
Java言語プログラムと、音楽の...
-
イベント処理について(文字列を...
-
C#でキーイベントが発生しない...
-
C# DataGridView列カスタマイズ
-
C#でのWNetAddConnection3の使...
-
コンポジションについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
大量のデータを読み込んで表示...
-
C#で、あるクラスのメンバーす...
-
C#でのWNetAddConnection3の使...
-
C# visibleプロパティをfalseに...
-
ユーザーコントロールを動的に...
-
C#でキーイベントが発生しない...
-
Junitテストでvoid戻り値メッソ...
-
C# 半角カナの文字化けについて
-
[C#.net]スレッド化された別フ...
-
C# WinForm のDataGridView Cel...
-
C# MouseHoverを何度も呼ぶには
-
C#単体テストで、UnitTestの使...
-
プログラミング(Java)じゃん...
-
C#から、C++で作成したdll内の...
-
アプレットでマウスイベントが...
-
JTable で複数行の編集
-
C# 矢印キーの取得
-
GetDIBits関数の使い方について
-
画像を順番に点滅させたい
-
正規表現
おすすめ情報
添付1
【Windowsフォームアプリ】
using Microsoft.VisualBasic.FileIO;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace CSV
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void readCSV()
{
TextFieldParser parser = new TextFieldParser("USDJPY.csv", System.Text.Encoding.GetEncoding("Shift_JIS"));
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
parser.SetDelimiters(",");
parser.ReadLine();
DateTime dt_start = DateTime.Parse("2022-12-29 00:00:00");
DateTime dt_end = DateTime.Parse("2022-12-30 23:59:00");
while (parser.EndOfData == false)
{
string[] column = parser.ReadFields();
DateTime dt = DateTime.Parse(
column[0].Substring(0, 4) + "-" +
String.Format("{0:D2}", column[0].Substring(5, 2)) + "-" +
String.Format("{0:D2}", column[0].Substring(8, 2)) + " " +
String.Format("{0:D2}", column[1].Substring(0, 2)) + ":" +
String.Format("{0:D2}", column[1].Substring(3, 2)) + ":00");
textBox1.AppendText(column[0] + Environment.NewLine);
if (dt < dt_start) continue;
if (dt > dt_end) continue;
textBox1.AppendText("■" + column[0] + Environment.NewLine);
}
}
private void button1_Click(object sender, EventArgs e)
{
readCSV();
}
}
}
上のコードを繋げてください(使いづらい・・・)
ちなみにUSDJPY.csvには
2005.01.10,02:31,104.79,104.79,104.79,104.79,5
2005.01.10,02:32,104.79,104.78,104.79,104.78,6
2005.01.10,02:33,104.78,104.77,104.78,104.77,5
のようなデータが67万行入っています(汗)
【コンソールアプリ】
(TextFieldParserで呼び出し処理)
long startcount;
QueryPerformanceCounter(out startcount);
while (parser.EndOfData == false)
{
Console.WriteLine(parser.ReadLine());
}
long endcount;
QueryPerformanceCounter(out endcount);
(結果表示)