Click here to Skip to main content
15,883,804 members
Articles / Desktop Programming / Win32

FileSnap: A Windows Library for Differential File Snapshots!

Rate me:
Please Sign up or sign in to vote.
4.62/5 (5 votes)
13 Feb 2019CPOL2 min read 15.6K   120   14   3
Include file versioning, snapshots and incremental backups in a file

Introduction

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.

Background

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

C++
class FILESNAP
{
public:
    struct alignas(8)  FSITEM
    {
        CLSID cid = FILESNAP::GUID_HEADER;
        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!

History

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

License

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


Written By
Software Developer
Greece Greece
I'm working in C++, PHP , Java, Windows, iOS, Android and Web (HTML/Javascript/CSS).

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

My home page: https://www.turbo-play.com

Comments and Discussions

 
QuestionMessage Closed Pin
16-Aug-21 22:48
kyleoliver2616-Aug-21 22:48 
SuggestionUse named constants instead of direct values? Pin
Chad3F19-Feb-19 8:57
Chad3F19-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.