Click here to Skip to main content
13,897,336 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


14 bookmarked
Posted 7 Oct 2017
Licenced CPOL

FileSnap: A Windows Library for Differential File Snapshots!

, 13 Feb 2019
Rate this:
Please Sign up or sign in to vote.
Include file versioning, snapshots and incremental backups in a file


Often, you want to have multiple versions of a file, but not rely on Windows NTFS versioning. Here is a simple Win32 class that you can easily use.


You need:

The ZIP includes a ready-to-use Notepad which demonstrates the library in a text editor (Finalize() and keyboard shortcuts are not there yet). A simple 1.stxt file is there to open.

Using the Code

    struct alignas(8)  FSITEM
        unsigned long long DiffAt = 0; 
        FILETIME created = ti();
        FILETIME updated = ti();
        unsigned long long i = 0;
        unsigned long long at = 0;
        unsigned long long sz = 0;
        unsigned long long extradatasize = 0;

    inline bool BuildMap(vector<FSITEM>& fsx);
    FILESNAP(const wchar_t* fi);
    inline bool SetSnap(size_t idx,int CommitForce = 0);
    inline bool Create(DWORD Access= GENERIC_READ | GENERIC_WRITE, DWORD Share = 0, 
          LPSECURITY_ATTRIBUTES Atrs = 0, DWORD Disp = CREATE_NEW, DWORD Flags = 0);
    inline unsigned long long Size();
    inline bool Finalize();
    inline bool Commit(size_t At,int Mode);
    inline HANDLE GetH();
    inline BOOL Write(const char* d, unsigned long long sz2);
    inline BOOL Read(char* d, unsigned long long sz2);
    inline unsigned long long SetFilePointer(unsigned long long s, DWORD m = FILE_BEGIN);
    inline BOOL SetEnd();
    inline void Close();

Working with the Class

  • You want to create a new file, you simply pass the name to the FILESNAP constructor.
  • You call Create() with the CreateFile flag CREATE_NEW to create the file.
  • You write to the file using Write().
  • When you want to save the current version, you call Commit(0,0). For the first save, Commit() ignores the two parameters.
  • You keep writing to the file using Write().
  • The next Commit() call will save the current contents as a differential backup. If the Mode parameter is 0, then Commit() saves as a differential backup to the first commit always. If the Mode parameter is 1, then Commit() saves as a differential backup to the specified commit number as the At parameter. This allows you to either use differential or incremental backups.
  • You keep writing, reading or else to the current handle using the Read(), Write(), SetEnd(), SetFilePointer(), Size() and GetH() function which returns the current HANDLE that you can use in other file functions.
  • If you want to revert to a specific saving, use SetSnap. CommitForce can be 0, 1 or 2:
    • 0 means that if the file exists already, the function fails.
    • 1 means that if the file exists already, a commit is taken before reverting.
    • 2 does not commit before reverting.
  • After you have used SetSnap(), Read()/Write()/GetH() etc. operate on the reverted data.
  • Close() will close the file (it does not commit), and delete all temporary files used by the class.


When you open an existing file, the class automatically calls SetSnap() on the last snapshot found in the file. You can call BuildMap() to return a FSITEM array of all snapshots included in the file.

If you build files with mostly differential backups (related to the first snapshot), then the file will be larger, but quicker to open because only one operation will be done (the comparison between the first and the opened snapshot).

If you build files with mostly incremental backups (related to the last snapshot), then the file will be smaller, but slower to open because all snapshots must be processed when a snapshot is loaded.

Use GetH() with care, because the HANDLE it returns is not valid anymore when Commit() or SetSnap() is called.

Have fun!


  • 19/10/2017 - Some typos
  • 8/10/2017 - First release


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Michael Chourdakis
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS and Android.

I 've a PhD in Digital Signal Processing and Artificial Intelligence and I specialize in Pro Audio and AI applications.

My home page:

You may also be interested in...


Comments and Discussions

SuggestionUse named constants instead of direct values? Pin
Chad3F19-Feb-19 8:57
memberChad3F19-Feb-19 8:57 
QuestionCan it be functional in Windows 10? Pin
iRupz18-Feb-19 17:17
professionaliRupz18-Feb-19 17:17 
Questionhave you consider to post this as a tip? Pin
Nelek8-Oct-17 8:57
protectorNelek8-Oct-17 8:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190306.1 | Last Updated 14 Feb 2019
Article Copyright 2017 by Michael Chourdakis
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid