Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
ThroughTmpFileWriter.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_IO_FileSystem_ThroughTmpFileWriter_h_
5#define _Stroika_Foundation_IO_FileSystem_ThroughTmpFileWriter_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <filesystem>
10
12
13/**
14 * \file
15 *
16 * \note Code-Status: <a href="Code-Status.md#Release">Release</a>
17 */
18
20
21 using Characters::String;
22
23 /**
24 * \brief utility to atomically update/write a file.
25 *
26 * Specify the name of a file to write, and an optional file suffix for a tempfile, and
27 * support writing through the tempfile, and then atomicly renaming the file when done.
28 *
29 * Even in case of failure, assure the tmpfile is removed.
30 *
31 * There is no need to first remove 'realFileName' - as this will not fail because it already exists (unless
32 * we don't have permission to remove it).
33 *
34 * The point of this is to allow writing a file in such a way that the entire file write is
35 * atomic. We don't want to partially update a file and upon failure, leave it corrupted (partly updated).
36 *
37 * Using this class, you create a tempfile, write to it, and the Commit () the change. NOTE,
38 * it is REQUIRED you call Commit () after all writing to tmpfile is done (and closed),
39 * otherwise the changes are abandoned.
40 *
41 * \par Example Usage
42 * \code
43 * ThroughTmpFileWriter tmpFile{targetFileName};
44 * IO::FileSystem::FileOutputStream::Ptr outStream = IO::FileSystem::FileOutputStream::New (tmpFile.GetFilePath ());
45 * YourCodeToWriteDataToStream (your_data, out);
46 * out.clear(); // close like this so we can throw exception - cannot throw if we count on DTOR
47 * tmpFile.Commit (); // any exceptions cause the tmp file to be automatically cleaned up
48 * \endcode
49 *
50 * \par Example Usage
51 * \code
52 * ThroughTmpFileWriter tmpFile{targetFileName};
53 * {
54 * IO::FileSystem::FileOutputStream::Ptr outStream = IO::FileSystem::FileOutputStream::New (tmpFile.GetFilePath ());
55 * YourCodeToWriteDataToStream (your_data, outStream);
56 * // use scope (braces) to force close before commit (or call out.clear())
57 * }
58 * tmpFile.Commit (); // any exceptions cause the tmp file to be automatically cleaned up
59 * \endcode
60 *
61 * \note - despite the similaries, this does not use AppTempFile module, because that writes in a specific place,
62 * and for 'rename' to work, it must be in the same filesystem (disk/os dependent), so write in same folder (is what this does).
63 */
65 public:
66 ThroughTmpFileWriter (const filesystem::path& realFileName, const String& tmpSuffix = ".tmp"sv);
69
70 public:
71 nonvirtual ThroughTmpFileWriter& operator= (const ThroughTmpFileWriter&) = delete;
72
73 public:
74 /**
75 */
76 nonvirtual filesystem::path GetTmpFilePath () const;
77
78 public:
79 /**
80 */
81 nonvirtual filesystem::path GetRealFilePath () const;
82
83 public:
84 /**
85 * Before commit this returns the tmpfile name. After commit returns the eventual file name.
86 */
87 nonvirtual filesystem::path GetFilePath () const;
88
89 public:
90 /**
91 * tmpfile must have been closed the time we call Commit, and it atomicly renames the file
92 * to the target name. This CAN fail (in which case cleanup is handled automatically)
93 */
94 nonvirtual void Commit ();
95
96 private:
97 filesystem::path fRealFilePath_;
98 filesystem::path fTmpFilePath_;
99 };
100
101}
102
103/*
104 ********************************************************************************
105 ***************************** Implementation Details ***************************
106 ********************************************************************************
107 */
108#include "ThroughTmpFileWriter.inl"
109
110#endif /*_Stroika_Foundation_IO_FileSystem_ThroughTmpFileWriter_h_*/
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201