HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
atomicOfstreamWrapper.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
8 #define PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
9 
10 /// \file tf/atomicOfstreamWrapper.h
11 /// Atomic file writer with ofstream interface.
12 
13 #include "pxr/pxr.h"
14 #include "pxr/base/tf/api.h"
15 
16 #include <fstream>
17 #include <string>
18 
20 
21 /// \class TfAtomicOfstreamWrapper
22 ///
23 /// A class that wraps a file output stream, providing improved tolerance for
24 /// write failures. The wrapper opens an output file stream to a temporary
25 /// file on the same file system as the desired destination file, and if no
26 /// errors occur while writing the temporary file, it can be renamed
27 /// atomically to the destination file name. In this way, write failures are
28 /// encountered while writing the temporary file content, rather than while
29 /// writing the destination file. This ensures that, if the destination
30 /// existed prior to writing, it is left untouched in the event of a write
31 /// failure, and if the destination did not exist, a partial file is not
32 /// written.
33 ///
34 /// \section cppcode_AtomicOfstreamWrapper Example
35 /// \code
36 /// // Create a new wrapper with the destination file path.
37 /// TfAtomicOfstreamWrapper wrapper("/home/user/realFile.txt");
38 ///
39 /// // Open the wrapped stream.
40 /// string reason;
41 /// if (not wrapper.Open(&reason)) {
42 /// TF_RUNTIME_ERROR(reason);
43 /// }
44 ///
45 /// // Write content to the wrapped stream.
46 /// bool ok = WriteContentToStream(wrapper.GetStream());
47 ///
48 /// if (ok) {
49 /// // No errors encountered, rename the temporary file to the real name.
50 /// string reason;
51 /// if (not wrapper.Commit(&reason)) {
52 /// TF_RUNTIME_ERROR(reason);
53 /// }
54 /// }
55 ///
56 /// // If wrapper goes out of scope without being Commit()ed, Cancel() is
57 /// // called, and the temporary file is removed.
58 /// \endcode
59 ///
61 {
63  TfAtomicOfstreamWrapper& operator=(
64  const TfAtomicOfstreamWrapper&) = delete;
65 public:
66  /// Constructor.
67  TF_API explicit TfAtomicOfstreamWrapper(const std::string& filePath);
68 
69  /// Destructor. Calls Cancel().
71 
72  /// Opens the temporary file for writing. If the destination directory
73  /// does not exist, it is created. If the destination directory exists but
74  /// is unwritable, the destination directory cannot be created, or the
75  /// temporary file cannot be opened for writing in the destination
76  /// directory, this method returns false and \p reason is set to the
77  /// reason for failure.
78  TF_API bool Open(std::string* reason = 0);
79 
80  /// Synchronizes the temporary file contents to disk, and renames the
81  /// temporary file into the file path passed to Open. If the file path
82  /// passed to the constructor names an existing file, the file, the file
83  /// is atomically replaced with the temporary file. If the rename fails,
84  /// false is returned and \p reason is set to the reason for failure.
85  TF_API bool Commit(std::string* reason = 0);
86 
87  /// Closes the temporary file and removes it from disk, if it exists.
88  TF_API bool Cancel(std::string* reason = 0);
89 
90  /// Returns the stream. If this is called before a call to Open, the
91  /// returned file stream is not yet initialized. If called after Commit or
92  /// Cancel, the returned file stream is closed.
93  std::ofstream& GetStream() { return _stream; }
94 
95 private:
96  std::string _filePath;
97  std::string _tmpFilePath;
98  std::ofstream _stream;
99 };
100 
102 
103 #endif // PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
#define TF_API
Definition: api.h:23
TF_API bool Commit(std::string *reason=0)
std::ofstream ofstream
Definition: filesystem.h:58
TF_API bool Cancel(std::string *reason=0)
Closes the temporary file and removes it from disk, if it exists.
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
TF_API ~TfAtomicOfstreamWrapper()
Destructor. Calls Cancel().
TF_API bool Open(std::string *reason=0)