cppBuilder
fileIO
#migrated

C++ Builder > How to check file deletion/modification time

More than 1 year has passed since last update.
動作環境
C++ Builder XE4

Purpose

To know when the file is deleted/modified.

v0.1

Implementation

Check interval is 100msec.

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // 
    TButton *B_clear;
    TMemo *Memo1;
    TTimer *Timer1;
    TEdit *E_filename;
    TOpenDialog *OpenDialog1;
    TButton *B_selectFile;
    TButton *B_start;
    void __fastcall FormShow(TObject *Sender);
    void __fastcall Timer1Timer(TObject *Sender);
    void __fastcall B_clearClick(TObject *Sender);
    void __fastcall B_startClick(TObject *Sender);
    void __fastcall B_selectFileClick(TObject *Sender);
private:    //
    void __fastcall CheckFileModification(void);
public:     //
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IOUtils.hpp> // for TDirectory.XXX
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    Memo1->Clear();
    E_filename->Text = L"";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    CheckFileModification();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckFileModification(void)
{
    static TDateTime preDt;
    static bool isDeleted = false;

    if (E_filename->Text.Length() == 0) {
        return;
    }

    if (FileExists(E_filename->Text) == false) {
        if (isDeleted == false) {
            isDeleted = true;
            Memo1->Lines->Add(L"Deleted on " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
        }
        return;
    }

    TDateTime curDt;
    FileAge(E_filename->Text, curDt);
    if (preDt != curDt) {
        isDeleted = false;
        preDt = curDt;
        Memo1->Lines->Add(L"Modified on " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
    }
}


void __fastcall TForm1::B_clearClick(TObject *Sender)
{
    Memo1->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_startClick(TObject *Sender)
{
    Timer1->Enabled = false;
    Timer1->Interval = 100; // msec
    Timer1->Enabled = true;

    B_start->Caption = L"Started";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_selectFileClick(TObject *Sender)
{
    if (OpenDialog1->Execute() == false) {
        return;
    }

    E_filename->Text = OpenDialog1->FileName;
}
//---------------------------------------------------------------------------

How to use

  1. Select the target file with [Browse]
  2. Start the scan with [Start]
  3. Use [Log Clear] to clear the log
    • only if necessary

To change the target file, just restart the software.

Example

qiita.png

download

v0.1: https://www.dropbox.com/s/f9mbj2dxpadkdvt/FileModifyChecker_170810.exe?dl=0

v0.2

added following features

  • Copy file feature
    • with the timestamp of the modification
  • Combobox to change [check interval]

code

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.Dialogs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // coponents managed by IDE
    TButton *B_clear;
    TMemo *Memo1;
    TTimer *Timer1;
    TEdit *E_filename;
    TOpenDialog *OpenDialog1;
    TButton *B_selectFile;
    TButton *B_start;
    TCheckBox *CHK_copyFile;
    TComboBox *CB_interval_msec;
    TLabel *Label1;
    void __fastcall FormShow(TObject *Sender);
    void __fastcall Timer1Timer(TObject *Sender);
    void __fastcall B_clearClick(TObject *Sender);
    void __fastcall B_startClick(TObject *Sender);
    void __fastcall B_selectFileClick(TObject *Sender);
private:    // user declaration
    void __fastcall CheckFileModification(void);
    void __fastcall BackupFile(void);
public:     // user declaration
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <IOUtils.hpp> // for TDirectory.XXX
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------

/*
v0.2 Aug. 11, 2017
    - add check interval combobox
    - add copy file feature [optional]
v0.1 Aug. 10, 2017
    - just display timestamps of [modification/deletion]
*/

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    Memo1->Clear();
    E_filename->Text = L"";
    CB_interval_msec->ItemIndex = 0;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    CheckFileModification();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BackupFile(void)
{
    if (CHK_copyFile->Checked == false) {
        return;
    }

    String fromfile = E_filename->Text; // original file (e.g. .git/config)
    String tofile; // backup file (e.g. config_20170811_123045_314)

    String curDir = GetCurrentDir();
    String timeStamp = Now().FormatString(L"yyyymmdd_hhnnss_zzz");
    tofile = curDir + L"\\" + ExtractFileName(fromfile);
    String ext = ExtractFileExt(fromfile);
    int len_subtracted = tofile.Length() - ext.Length();
    tofile = tofile.SubString(0, len_subtracted); // without extension
    tofile = tofile + L"_" + timeStamp + ext; // e.g. config_20170811_123045_314

    //Memo1->Lines->Add(Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
    TFile::Copy(fromfile, tofile, /* overwrite=*/true); // about 2msec for copying a textfile (35 bytes)
    //Memo1->Lines->Add(Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
}

void __fastcall TForm1::CheckFileModification(void)
{
    static TDateTime preDt;
    static bool isDeleted = false;

    if (E_filename->Text.Length() == 0) {
        return;
    }

    if (FileExists(E_filename->Text) == false) {
        if (isDeleted == false) {
            isDeleted = true;
            Memo1->Lines->Add(L"Deleted on " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
        }
        return;
    }

    TDateTime curDt;
    FileAge(E_filename->Text, curDt);
    if (preDt != curDt) {
        isDeleted = false;
        preDt = curDt;
        BackupFile();
        Memo1->Lines->Add(L"Modified on " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz"));
    }
}

void __fastcall TForm1::B_clearClick(TObject *Sender)
{
    String msg = L"Clear log?";

    if (Application->MessageBox(msg.c_str(), L"Confirmation",MB_OKCANCEL | MB_DEFBUTTON2) == idCancel) {
        return;
    }

    Memo1->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_startClick(TObject *Sender)
{
    Timer1->Enabled = false;
    int idx = CB_interval_msec->ItemIndex;
    int itvl_msec = StrToIntDef(CB_interval_msec->Items->Strings[idx], 100);
    Timer1->Interval = itvl_msec;
    Timer1->Enabled = true;

    // just disalbe for not handling [restart] with other conditions
    B_start->Caption = L"Started";
    CB_interval_msec->Enabled = false;
    CHK_copyFile->Enabled = false;
    B_selectFile->Enabled = false;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::B_selectFileClick(TObject *Sender)
{
    if (OpenDialog1->Execute() == false) {
        return;
    }

    E_filename->Text = OpenDialog1->FileName;
}
//---------------------------------------------------------------------------

How to use

Use the .exe file in a some folder, because the [Copyfile] feature will copy the target file to the folder where the application is executed.

  1. Select the target file with [Browse]
  2. Check the [Copyfile] if the file copy is desired
  3. Select check interval
  4. Start the scan with [Start]
  5. Use [Log Clear] to clear the log
    • only if necessary

To change the target file, just restart the software.

Example

qiita.png

qiita2.png

sample_170810_20170811_130649_746.txt
aaabbb
dffd
cccfdsfd
fad
fds
d

sample_170810_20170811_130710_790.txt
aaabbb
dffd
cccfdsfd
fad
fds
d
hello world

Disclaimer

Copy file feature will take the copy of the file.
If the target file is highly-frequently modified, and the copy feature works so frequently, it may cause a file-lock.

Please do not use this feature for your daily operational work, and use it only for test.

download

v0.2 https://www.dropbox.com/s/hk354a3djydd627/FileModifyChecker_170810.exe?dl=0