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 Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
25 #define PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
26 
27 /// \file tf/atomicOfstreamWrapper.h
28 /// Atomic file writer with ofstream interface.
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/tf/api.h"
32 
33 #include <fstream>
34 #include <string>
35 
37 
38 /// \class TfAtomicOfstreamWrapper
39 ///
40 /// A class that wraps a file output stream, providing improved tolerance for
41 /// write failures. The wrapper opens an output file stream to a temporary
42 /// file on the same file system as the desired destination file, and if no
43 /// errors occur while writing the temporary file, it can be renamed
44 /// atomically to the destination file name. In this way, write failures are
45 /// encountered while writing the temporary file content, rather than while
46 /// writing the destination file. This ensures that, if the destination
47 /// existed prior to writing, it is left untouched in the event of a write
48 /// failure, and if the destination did not exist, a partial file is not
49 /// written.
50 ///
51 /// \section cppcode_AtomicOfstreamWrapper Example
52 /// \code
53 /// // Create a new wrapper with the destination file path.
54 /// TfAtomicOfstreamWrapper wrapper("/home/user/realFile.txt");
55 ///
56 /// // Open the wrapped stream.
57 /// string reason;
58 /// if (not wrapper.Open(&reason)) {
59 /// TF_RUNTIME_ERROR(reason);
60 /// }
61 ///
62 /// // Write content to the wrapped stream.
63 /// bool ok = WriteContentToStream(wrapper.GetStream());
64 ///
65 /// if (ok) {
66 /// // No errors encountered, rename the temporary file to the real name.
67 /// string reason;
68 /// if (not wrapper.Commit(&reason)) {
69 /// TF_RUNTIME_ERROR(reason);
70 /// }
71 /// }
72 ///
73 /// // If wrapper goes out of scope without being Commit()ed, Cancel() is
74 /// // called, and the temporary file is removed.
75 /// \endcode
76 ///
78 {
80  TfAtomicOfstreamWrapper& operator=(
81  const TfAtomicOfstreamWrapper&) = delete;
82 public:
83  /// Constructor.
84  TF_API explicit TfAtomicOfstreamWrapper(const std::string& filePath);
85 
86  /// Destructor. Calls Cancel().
88 
89  /// Opens the temporary file for writing. If the destination directory
90  /// does not exist, it is created. If the destination directory exists but
91  /// is unwritable, the destination directory cannot be created, or the
92  /// temporary file cannot be opened for writing in the destination
93  /// directory, this method returns false and \p reason is set to the
94  /// reason for failure.
95  TF_API bool Open(std::string* reason = 0);
96 
97  /// Synchronizes the temporary file contents to disk, and renames the
98  /// temporary file into the file path passed to Open. If the file path
99  /// passed to the constructor names an existing file, the file, the file
100  /// is atomically replaced with the temporary file. If the rename fails,
101  /// false is returned and \p reason is set to the reason for failure.
102  TF_API bool Commit(std::string* reason = 0);
103 
104  /// Closes the temporary file and removes it from disk, if it exists.
105  TF_API bool Cancel(std::string* reason = 0);
106 
107  /// Returns the stream. If this is called before a call to Open, the
108  /// returned file stream is not yet initialized. If called after Commit or
109  /// Cancel, the returned file stream is closed.
110  std::ofstream& GetStream() { return _stream; }
111 
112 private:
113  std::string _filePath;
114  std::string _tmpFilePath;
115  std::ofstream _stream;
116 };
117 
119 
120 #endif // PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
#define TF_API
Definition: api.h:40
TF_API bool Commit(std::string *reason=0)
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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:1441
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TF_API ~TfAtomicOfstreamWrapper()
Destructor. Calls Cancel().
TF_API bool Open(std::string *reason=0)