現在ある階層にある全てのテキストファイルの中身を読み取るコードを書いています。
その階層にはテキストファイルしかなく、そのファイルパスは全て取得できているとします。
現状では、StreamReaderクラスのReadLineを用いてファイルを読み取り、それをループさせて複数ファイルを読み取っています。
ただこの方法だとどうしても速度的に遅くなってしまいます。一つ一つのファイル自体は大した容量ではありません(最大でも200KB程度)が、ファイル数が100個近くあります。
そこで、もし高速で複数のテキストファイルを読み取る方法があれば教えて頂けませんか。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
こんにちは。
ippeiさんの回答に
SSDであれば並列化すればした分だけ早くなると思います。
とあったので、
並列
処理する方法について、
(試してないので、just an ideaで恐縮なのですが、)
以下のような方法を思いつきました。
(1)対象の約100個のテキストファイルの名前を
001.txt, 002.txt .. 099.txt, 100.txt, ... 1XX.txt
というように番号をつける。
番号でなくても、何らかの方法で、対象の約100個のファイルを
均等な個数のグループに分けて、そのグループに対して
以下の(2)のような起動の仕方ができればOKです。
(2)C#で開発するファイル処理プログラムの実行ファイルを仮に
readfiles.exe
とし、以下のようなコマンドライン引数を取れるようにする。
readfiles [開始ファイル番号] [終了ファイル番号]
例)readfiles 021 030 - - - 021.txt から030.txtまでを処理する。
(3)以下のような内容のバッチファイルを作成して実行
lang
1@echo off 2start readfiles 001 020 3start readfiles 021 040 4start readfiles 041 060 5start readfiles 061 080 6start readfiles 081 100 7start readfiles 101 1XX
このreadfiles自体の最適化は、htsignさんご回答の方法を使うなどで
もちろん行うとして、上記のようなバッチで20個のファイルを1個ずつ
処理していくコマンドを5個と、XX個のファイルを処理するコマンド1個
の計6個のコマンドをバックグラウンドで走らせることで高速化を図ります。
(もちろん、10個のファイルを処理するコマンド10+α個並行に、でも
よいのですが)
参考になれば幸いです。
投稿2015/05/05 16:37
編集2015/05/05 16:59総合スコア9058
0
ベストアンサー
実装にもよるかと思いますが、System.IO.File
クラスのReadAllTextメソッドで一気に読み取る方が速かったです。
lang
1string[] files = Directory.GetFiles(Path.GetTempPath(), "*.log"); 2var sizes = new List<int>(); 3var sw = Stopwatch.StartNew(); 4 5foreach (var file in files) 6{ 7 try 8 { 9 var text = File.ReadAllText(file); 10 sizes.Add(text.Length); 11 if (sizes.Count >= 1000) break; 12 } 13 catch (IOException) { } 14} 15Console.WriteLine(sw.ElapsedMilliseconds + "ms"); 16Console.WriteLine("filecounts: {0}, avg size: {1:F2}", sizes.Count, sizes.Average());
出力は
5767ms
filecount: 1000, avg size: 792024.91
でした。
続いて読み取り部分を
lang
1var text = new StringBuilder(); 2using (var sr = new StreamReader(file)) 3{ 4 while (!sr.EndOfStream) 5 { 6 text.AppendLine(sr.ReadLine()); 7 } 8}
としたバージョンで測ってみましたが、
6571ms
filecount: 1000, avg size: 792051.48
このような感じでした。
ファイルサイズが違ってるのは…なんかミスってるんでしょうね。文字コードあたりの問題でしょうか。
ともあれReadAllTextの方が速く、これはそれぞれ10回試行しても逆転しませんでした。
ファイルサイズ200KB程度のファイルが100個未満しかないのに無視できないほどの時間がかかるのだとしたら、もしかするとStringBuilderクラスを使っていないということはありませんか?
ちなみに、ご存じかもしれませんがStreamReaderクラスにも一気に読み取るReadToEndメソッドがあります。
投稿2015/05/05 15:58
編集2015/05/05 19:52総合スコア870
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
200KBが100ファイルだと20MBなので格納先がHDDの場合、読み込みを並列化するとやや遅くなりそうですが、SSDであれば並列化すればした分だけ早くなると思います。
投稿2015/05/05 15:54
編集2015/05/06 02:49総合スコア91
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/05/05 22:41