差分ファイル取得モジュール

仕様変更で、差分ファイル作成ツールを刷新しようと考えてます。そこで、まず二フォルダ間の差分ファイルを取得するモジュールを作りました。速度は Holy Knights Ver.2.13(X'mas Edition) と HolyKnights Ver.2.10 の差分ファイルを出力するのに 0.4 秒強ぐらいで、十分許容範囲でしょう。他の方のモジュールに依存しまくりなんで、どうかとも思いますが、一応スクリプトを公開しときます。

//  二フォルダ間の差分ファイルを調べるモジュール
// kernel32.as、dirlist2代替モジュール、CRC32取得モジュールに依存する
#ifndef modDifflist
#include "kernel32.as"
#include "dirlist2.hsp"
#include "crc32.hsp"

#module modDifflist
    #uselib "shlwapi"
    #cfunc PathMatchSpec "PathMatchSpecA" sptr, sptr
    // difflist NewFolder, OldFolder, ExcludeFileList, Mode
    //
    //  DiffListBuf      : 結果を格納する変数
    //  NewFolder        : 比較する新しいフォルダ
    //  OldFolder        : 比較する古いフォルダ
    //  FileMask         : 検索するファイルのワイルドカード
    //  GetMode          : 検索するファイルの取得モード
    //  ExcludeFileList  : 差分ファイルから除外するファイルのリスト
    //  DiffMode         : 差分ファイルを調べるモード
    //
    //  FileMask は NewFolder 内のファイルを検索するときのファイルマスク。
    //  ワイルドカードで指定する。("*.*"など)
    //
    //  GetMode は dirlist 命令で使う取得モード。
    //  サブフォルダも検索するときはそれと 8 の和。
    //
    //  ExcludeFileListは、差分ファイルから除外するファイルをワイルドカードで指定したものを改行で区切ったリスト。
    //
    //  DiffModeは以下の値の組み合わせ
    //   $0001 : 差分ファイルに入れる条件に「新しいファイル」を付け加える
    //   $0002 : 差分ファイルに入れる条件に「異なるサイズ」を付け加える
    //   $0004 : 差分ファイルに入れる条件に「新しい更新日時」を付け加える
    //   $0008 : 差分ファイルに入れる条件に「異なる更新日時」を付け加える
    //   $0010 : 差分ファイルに入れる条件に「異なるファイル内容」を付け加える
    //  これらの選択された条件のうち一つでも当てはまれば差分ファイルに入る
    #define global difflist( %1, %2, %3, %4 = "*.*", %5 = 9, %6 = "", %7 = $0013 ) _difflist %1, %2, %3, %4, %5, %6, %7
    #deffunc _difflist var DiffListBuf, str NewFolder, str OldFolder, str FileMask, int GetMode, str _ExcludeFileList, int DiffMode
        StartDir = dir_cur

        //改行で区切られた除外リストを配列変数に変換
        ExcludeFileList = _ExcludeFileList
        notesel ExcludeFileList
        sdim ExcludeFile, 260, notemax
        noteunsel
        idx = 0
        repeat length( ExcludeFile )
            getstr ExcludeFile.cnt, ExcludeFileList, idx
            idx += strsize
        loop
        
        chdir NewFolder
        dirlist2 NewFolderFileList, FileMask, GetMode
        nFiles = stat

        nDiffFile = 0

        //結果格納文字列変数
        DiffListBufSz = 65536
        sdim DiffListBuf, DiffListBufSz
        DiffListBufIdx = 0

        idx = 0
        repeat nFiles
            getstr buf, NewFolderFileList, idx
            if strsize == 0 : break
            idx += strsize
            //除外リストに当てはまるか
            ExcludeFlag = 0
            repeat length( ExcludeFile )
                if PathMatchSpec( buf, ExcludeFile.cnt ) : ExcludeFlag = 1 : continue
            loop
            if ExcludeFlag : continue

            //ファイルが異なっているかチェック

            FileName = NewFolder + "\\" + buf, OldFolder + "\\" + buf

            repeat 2
                exist FileName.cnt
                FileSz.cnt = strsize
            loop

            //古いフォルダーに当該ファイルが存在しなかったら、差分ファイルへ入れる
            if ( DiffMode & 1 ) & FileSz.1 == -1 : gosub *AddToList : continue
            
            //ファイルサイズが異なっていたら、差分ファイルへ入れる
            if ( DiffMode >> 1 & 1 ) & FileSz.0 != FileSz.1 : gosub *AddToList : continue
            
            //更新日時
            if DiffMode >> 2 & 3 {
                ddim FileTime, 2
                repeat 2
                    CreateFile FileName.cnt, 0, 0, 0, 3, 0, 0
                    hFile = stat
                    GetFileTime hFile, 0, 0, varptr( FileTime ) + 8 * cnt
                    CloseHandle hFile
                loop
                CompareFileTime varptr( FileTime ), varptr( FileTime ) + 8
                //新しいファイルの更新日時が古いファイルのそれより新しかったら、差分ファイルへ入れる
                if DiffMode >> 2 & 1 {
                    if stat == 1 : gosub *AddToList : continue
                }
                //新しいファイルの更新日時が古いファイルのそれと異なっていたら、差分ファイルへ入れる
                if DiffMode >> 3 & 1 {
                    if stat != 0 : gosub *AddToList : continue
                }
            }
            //ファイルの内容(CRC32)が異なっていたら、差分ファイルへ入れる
            if DiffMode >> 4 & 1 {
                repeat 2
                    FileCrc = 0
                    if FileSz.cnt > 0 {
                        sdim FileBuf, FileSz.cnt
                        bload FileName.cnt, FileBuf
                        FileCrc.cnt = GetCrc32( FileBuf, FileSz.cnt, 0 )
                    }
                loop
                if FileCrc.0 != FileCrc.1 : gosub *AddToList : continue
            }
        loop
        return nDiffFile
*AddToList
    //ファイルが異なっていると判断できたので、リストに追加
    if DiffListIdx + 260 >= DiffListBufSz : DiffListBufSz += 65536 : memexpand DiffListBuf, DiffListBufSz
    poke DiffListBuf, DiffListBufIdx, buf + "\n"
    DiffListBufIdx += strsize
    nDiffFile ++
    return
#global
#endif

dirlist2.hsp はModule/修正版dirlist2 - HSP開発wikiのモジュールを自分の使いやすいように直したものです。具体的には以下のように改造しました。

このように、全然 hspext と互換性のない dirlist2 に改造しました。

「 crc32.hsp 」はつーさのくーかん | 「HSPが遅い」って書いたのは......にある CRC32 取得モジュール。これについて、使用していいか今まで確認していないまま使用してしまっていました。問い合わせると、使用していいとのことでした。確認せずに使用したしまったこと、お詫びします。

インフォメーション

公開日時
2007年6月16日 午後1時14分15秒
最終更新日時
2007年12月19日 午後10時6分6秒
カテゴリ
HSP