Wonderful! WordPress

習得中 Rust で 日付順 のファイル一覧取得と php でのコマンドラインツール

Page No.2

php でも全サブフォルダ下にある全ファイルの日付逆順リストを取得するコマンドラインツール

で、ふと思いついたのが、php って確かコマンドラインでも動いたんじゃなかったか、ってこと。php がコマンドラインで使えるなら、こんなプログラムはすぐ書けるだろうから、試しにやってみるかと。ちょっと調べてみると、コマンドラインでも使えて、ファイルにプログラムを書いて、コマンドラインからそのファイルを指定して php を実行させればいいだけのこと、とのことだった。

で、さっそく作ってやってみる。これが php だと、いともあっさりとパッと結果が表示される。千以上ファイルがあっても一瞬で処理が終わる。そしてこれはやはり Rust においてのやり方が間違っているに違いないと気づく。そして、改めて metadata() を調べてみると、やはりというか、ファイルをオープンする必要などなかったということです。

結果、やはり当然のこと Rust の方が速いのだろうけれど、php でもほとんど変わらないほどの速さで表示される。ファイルの数が何万とかになれば違いがわかるほどになるのかも。
と、いうことで、その php にて作ったものが下。ちなみにこの php を実行させるコマンドラインでのコマンドは、php のフォルダにパスが通っていて、このファイルのあるフォルダにてこう。コマンドラインの引数でオプション値を渡してもよし。でなければメッセージが表示されるのでコマンドラインから入力するもよし。デフォルト値も設定してあるので、入力せずリターンキーだけで済ませてもよし。

その後、使っていて思うことであるけれど、Windows を起動してその起動回で初めてこの Rust のプログラムを動かすときは、それはもう驚くほど遅い。やはりフリーズしているのではないかと思うほど遅い。これでは使えないと思うほど遅い。二度目以降は、実にあっさりと動きとても速い。やはり、どこかやり方がおかしいのかもしれないが、待たされている間は表示されるべきメッセージさえ無いので、Rust の起動に時間がかかるのかもしれない。php の方も一度目は少し待たされることになるが、Rust ほどではない。これも待たされるのはメッセージが表示されるまでなので、やはり php 自体の起動待ちなのではないかと思われる。と、いうことで、結果、使っているのは php の方となっている。

c:\server\cmd> php sort_date.php
Bash
CopyExpand
<?php
    $tarfile = 'e:\\capt\\imgs';
    $limit = 30;
    $noarg = true;

    // コマンドラインで php に引数を渡す場合、第一引数は $argv[1]、第二引数は $argv[2] と言った具合で取得できる
    if ( isset ( $argv[2] ) ) {
        $tarfile = $argv[2];
        $noarg = false;
    }
    if ( isset ( $argv[1] ) ) {
        $limit = ( int ) $argv[1];
        $noarg = false;
    }

    // コマンドライン引数にて引数を渡されなかった場合は、コマンドラインに入力させて取得する
    if ( $noarg ) {
        echo "\n" . '<<Sort all files order by new->old involve under sub-directry files!! >>' . "\n\n";

        echo 'Insert target directy : need full path.' . "\n";
        // コマンドライン入力値は下のパターンにて取得できる
        $stdind = trim( fgets( STDIN ) );

        if ( $stdind ) {
            $tarfile = $stdind;
            echo 'Target directry is < ' . $stdind . " >\n\n";
        } else {
            // 入力値がなければデフォルトの値を使う
            echo 'Target directry is default : < ' . $tarfile . " >\n\n";
        }

        echo 'Insert show files count.' . "\n";
        $stdinc = trim( fgets( STDIN ) );

        if ( $stdinc ) {
            $limit = ( int ) $stdinc;
            echo 'Show count is < ' . $stdinc . " >\n\n" . 'And progress start!' . "\n\n";
        } else {
            echo 'Show count is default value :< ' . ( string ) $limit . " >\n\n" . 'And progress start!' . "\n\n";
        }
    }

    $scount = 1;
    $datad = array();
    $datan = array();

    function show_file( $basepath, $dir ) {

        // 指定されたフォルダ下にあるフォルダとファイルを取得する
        // フォルダであれば自分自身を呼び、ファイルであればタイムスタンプを取得して配列に格納する

        global $tarfile, $datad, $datan;

        $path = $basepath . '\\' . $dir;

        if ( is_dir( $path ) ) {
            if ( '.' !== $dir and '..' !== $dir ) {

                $sfiles = scandir( $path );

                foreach ( $sfiles as $sfile ) {
                    $spath = $path . '\\' . $sfile;

                    if ( is_dir( $spath ) ) {

                        show_file ( $path, $sfile );
                    } else {
                        // ファイル名が長い場合は見づらくなるので40文字までにきる
                        $filename = mb_substr ( $sfile, 0, 40 );
                        $filetime = filemtime( $spath );

                        $datad[] = $filetime;
                        $datan[] = str_replace( $tarfile . '\\', '', $path ) . '> ' . $filename;
                    }
                }
            }

        } else {
            $filename = mb_substr ( $dir, 0, 40 );
            $filetime = filemtime( $path );

            $datad[] = $filetime;
            $datan[] = $filename;
        }
    }

    if ( file_exists( $tarfile ) ) {

        echo 'target dir : ' . $tarfile . "\n\n";

        $files = scandir( $tarfile );
        
        if ( $files ) {
            foreach ( $files as $file ) {

                show_file( $tarfile, $file );
            }

            if ( $datad ) {

                echo "\n" . 'Result - All files count : ' . count ( $datad ) . "\n\n";

                arsort( $datad );

                foreach ( $datad as $key => $val ) {

                    echo $scount . '> ' . str_replace( $tarfile . '\\', '', $datan[ key ] ) . ' - ' . date( 'Y-m-d H:i:s', $val ) . "\n";      

                    ++$scount;
                    if ( $scount > $limit ) {
                        break;
                    }
                }
            } else {
                echo 'Result - File none';
            }
        }
    } else {
        echo 'That file or directry is none.';
    }
?>
PHP
CopyExpand

おまけ Rust-analyzer の 変数の型や関数の引数の型のヒントを消す設定

今回のツールを作っている時に、Rust の新しいバージョンがあることを知って、さっそくバージョンアップさせた。すると、VScord で使っていた Rust 関連のプラグイン、確か RSL とか出ていたかと、が非推奨になったので、代替の Rust-analyzer を使ったほうがいい、とかなんとか表示が出ていた。まぁ、非推奨ならとさっそくその Rust-analyzer に代えてみたところ、なにやらやたらとマーキングされた文字列が多く表示されるようになった。変数の型などが表示されているのは見ればわかるけれど、知らずに初めて接した時にはすこし引いてしまった。

それにしても、ちょっとうっとうしい。はっきり言って邪魔である。ので、設定を開いてこれを表示させないようできないものかと、項目を探すこととなった。そして、それらの設定は以下の項目となる。設定のタグを出して rust で検索。スクロールさせていくと中ほどよりも少し下あたりで出てくる。消したいもののチェックを外せば表示されなくなる。なにかのショートカットキーで知りたいときだけ表示させるようにできれば便利なのだけれど。

関数の引数で設定されている型
Rust-analyzer > Inlay Hints > Parameter Hints: Enable

変数に設定されている型
Rust-analyzer > Inlay Hints > Type Hints: Enable

Sanbanse Funabashi
2010.10.24 sunrise

Top

スクロールさせるか画像をクリックすると元に戻ります。