我々は賢いので。

かんとーちほーのエンジニアの、仕事とか、趣味とか、いろいろなはなし。

趣味プログラムの補助ツールを作った。

前段

ツイッターの画像クローラ。

twitter4j使ってメディア(画像)URLを拾って来る、いわゆるクローラを作ってまして。

今は毎朝四時にそのツールを叩くようにタスクスケジューラ組んで、自分のツイート、或いはリツイートした画像ファイルを収集してまして。

正確に言うと、画像じゃなく画像URLの収集。

画像を直接落としてくるツールではなく、画像URLをひたすら拾って来るツール、と言う形で作っています。

画像URL(と、幾つかのメタデータ)を拾ってきて、それをテキストファイルに吐き出しまくるだけのもの。

で、これを別なツールで読み込んでダウンロードする、と言う形にしています。

URLログファイルが溜まっていく

TwitterのSearchAPIの一週間制限を突破する方法がどうしても解らなくて、仕方ないのでもう今後定期的にクロールして溜めていこう、という発想に至りました。

で、そうなるとですね、結構大量なテキストファイルが溜まっていくんですね。

単純にテキストファイルの数が多いってのも問題ですし、その中のデータは結構な率で重複していると言うのも問題。

ということで、以下の目的でファイルをマージしたいと言う要件が発生したわけですね。

  • 単純にテキストファイルの数を減らしたい。
  • ファイル内の重複データを減らしたい。

まぁ、ダウンロードツールはスキップ機能も持たせてるので、重複データが存在する事自体は別に問題ないッチャ無いんですけどね。

本題

ということで

やっと本題ですが、テキストファイルをマージして、ついでに重複排除する処理を組みました。

ツールと言うようなレベルじゃなく、単にやりたい事をダッと書いた、って程度ですね。

        static void Main( string[] args )
        {
            try
            {
                Execute( args );
            }
            catch ( Exception ex )
            {
                Console.WriteLine( ex.Message );
                Console.WriteLine( ex.StackTrace );
            }
        }

        private static void Execute( string[] args )
        {
            string timestamp = DateTime.Now.ToString("yyyy-MMdd-HHmmss");
            string path = $"archived-text-{timestamp}.txt";

            var files = args
                .AsEnumerable()
                .Select( x => new FileInfo(x) )
                .Where( file => file.Exists );


            // 取り敢えず最低限、重複排除するだけで実装。
            HashSet<string> unique = new HashSet<string>();

            using ( StreamWriter writer = File.CreateText( path ) )
            {
                foreach ( var file in files )
                {
                    var lines = File.ReadAllLines(file.FullName);
                    foreach ( var line in lines )
                    {
                        // 初出なら作ったファイルに書き込み。
                        if ( unique.Add( line ) )
                        {
                            writer.WriteLine( line );
                        }
                    }
                }
            }
        }

とにかくまず動かしてファイルを減らしたいと言う事で、スピードだけ最優先して突貫で作ったので、機能的にはもっと色々と拡張したり、汎用性を持たせたり、オプション機能を作ったり、 最終的にはクローラの定時処理と合わせて、自動的にアーカイブしてくれるような、そんな仕組みにしたいなぁとか思ってますが。

まぁそれはいずれやる事にしましょう。

ある程度形になったら、またGitHubにでも置いときましょう。