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 <hboost/noncopyable.hpp>
34 
35 #include <fstream>
36 #include <string>
37 
39 
40 /// \class TfAtomicOfstreamWrapper
41 ///
42 /// A class that wraps a file output stream, providing improved tolerance for
43 /// write failures. The wrapper opens an output file stream to a temporary
44 /// file on the same file system as the desired destination file, and if no
45 /// errors occur while writing the temporary file, it can be renamed
46 /// atomically to the destination file name. In this way, write failures are
47 /// encountered while writing the temporary file content, rather than while
48 /// writing the destination file. This ensures that, if the destination
49 /// existed prior to writing, it is left untouched in the event of a write
50 /// failure, and if the destination did not exist, a partial file is not
51 /// written.
52 ///
53 /// \section cppcode_AtomicOfstreamWrapper Example
54 /// \code
55 /// // Create a new wrapper with the destination file path.
56 /// TfAtomicOfstreamWrapper wrapper("/home/user/realFile.txt");
57 ///
58 /// // Open the wrapped stream.
59 /// string reason;
60 /// if (not wrapper.Open(&reason)) {
61 /// TF_RUNTIME_ERROR(reason);
62 /// }
63 ///
64 /// // Write content to the wrapped stream.
65 /// bool ok = WriteContentToStream(wrapper.GetStream());
66 ///
67 /// if (ok) {
68 /// // No errors encountered, rename the temporary file to the real name.
69 /// string reason;
70 /// if (not wrapper.Commit(&reason)) {
71 /// TF_RUNTIME_ERROR(reason);
72 /// }
73 /// }
74 ///
75 /// // If wrapper goes out of scope without being Commit()ed, Cancel() is
76 /// // called, and the temporary file is removed.
77 /// \endcode
78 ///
79 class TfAtomicOfstreamWrapper : hboost::noncopyable
80 {
81 public:
82  /// Constructor.
83  TF_API explicit TfAtomicOfstreamWrapper(const std::string& filePath);
84 
85  /// Destructor. Calls Cancel().
87 
88  /// Opens the temporary file for writing. If the destination directory
89  /// does not exist, it is created. If the destination directory exists but
90  /// is unwritable, the destination directory cannot be created, or the
91  /// temporary file cannot be opened for writing in the destination
92  /// directory, this method returns false and \p reason is set to the
93  /// reason for failure.
94  TF_API bool Open(std::string* reason = 0);
95 
96  /// Synchronizes the temporary file contents to disk, and renames the
97  /// temporary file into the file path passed to Open. If the file path
98  /// passed to the constructor names an existing file, the file, the file
99  /// is atomically replaced with the temporary file. If the rename fails,
100  /// false is returned and \p reason is set to the reason for failure.
101  TF_API bool Commit(std::string* reason = 0);
102 
103  /// Closes the temporary file and removes it from disk, if it exists.
104  TF_API bool Cancel(std::string* reason = 0);
105 
106  /// Returns the stream. If this is called before a call to Open, the
107  /// returned file stream is not yet initialized. If called after Commit or
108  /// Cancel, the returned file stream is closed.
109  std::ofstream& GetStream() { return _stream; }
110 
111 private:
112  std::string _filePath;
113  std::string _tmpFilePath;
114  std::ofstream _stream;
115 };
116 
118 
119 #endif // PXR_BASE_TF_ATOMIC_OFSTREAM_WRAPPER_H
#define TF_API
Definition: api.h:40
TF_API bool Commit(std::string *reason=0)
std::ofstream ofstream
Definition: filesystem.h:81
TF_API bool Cancel(std::string *reason=0)
Closes the temporary file and removes it from disk, if it exists.
TF_API TfAtomicOfstreamWrapper(const std::string &filePath)
Constructor.
GLsizei const GLchar *const * string
Definition: glew.h:1844
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
TF_API ~TfAtomicOfstreamWrapper()
Destructor. Calls Cancel().
TF_API bool Open(std::string *reason=0)