using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace CountWordsandLines1 { class Program { static void Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Specify a file name"); } else { var filename = args[0]; var encoding = Encoding.UTF8; // ファイルを読みこむ //if(File.Exists(filename)) //ファイルが存在するかは、File.Exists()か読み込み時例外のどっち? try { var lines = File.ReadLines(filename, encoding); Console.WriteLine("File name : {0} contains {1} words in {2} lines", filename, lines.Select(line => line.Length).Sum(), lines.Count()); } catch (FileNotFoundException e) { Console.WriteLine(e.StackTrace + "\n" + e.Message); } catch (System.Security.SecurityException e) { Console.WriteLine(e.StackTrace + "\n" + e.Message); } } } } }
File.ReadLines(string, Encoding)はどうやら.NET 4.0追加の新しい関数らしいです。私は最初ストリームを使うものだと思ってました。で、この関数は面白いことに、返り値がIEnumerable<string>です。
.NET Framework 4 の基本クラス ライブラリの新機能 - http://msdn.microsoft.com/ja-jp/magazine/ee428166.aspx
なので今回はこれを使って、LINQ拡張メソッドで文字数を数えてます。.Select(line => line.Length)で行ごとの文字数を数え、それを.Sum()で合計してます。
行数は、1行毎にIEnumerable<string>に突っ込まれているので、この要素数になります。
一応幾つかファイルを読み込んでみた結果では、合ってるみたいです。
ぎもん
- ファイルを読み込むときに、やはりファイルが存在するかは確かめると思うんだけど、これはFile.Exists()を使って事前に確かめるべきなのか?File.ReadLines()してみてFileNotFoundExceptionをcatchすることで把握するべきなのか?
- Encodingの問題 - 未知のファイルは多分事前にエンコーディングはわからないだろうけど、どうするんだろう。
- 容量の大きすぎるファイル問題 - GB級ファイルの問題とか、メモリをどうするかとか