/src/brpc/src/butil/files/file.h
Line  | Count  | Source  | 
1  |  | // Copyright (c) 2012 The Chromium Authors. All rights reserved.  | 
2  |  | // Use of this source code is governed by a BSD-style license that can be  | 
3  |  | // found in the LICENSE file.  | 
4  |  |  | 
5  |  | #ifndef BUTIL_FILES_FILE_H_  | 
6  |  | #define BUTIL_FILES_FILE_H_  | 
7  |  |  | 
8  |  | #include "butil/build_config.h"  | 
9  |  | #if defined(OS_WIN)  | 
10  |  | #include <windows.h>  | 
11  |  | #endif  | 
12  |  |  | 
13  |  | #if defined(OS_POSIX)  | 
14  |  | #include <sys/stat.h>  | 
15  |  | #endif  | 
16  |  |  | 
17  |  | #include <string>  | 
18  |  |  | 
19  |  | #include "butil/base_export.h"  | 
20  |  | #include "butil/basictypes.h"  | 
21  |  | #include "butil/files/scoped_file.h"  | 
22  |  | #include "butil/move.h"  | 
23  |  | #include "butil/time/time.h"  | 
24  |  |  | 
25  |  | #if defined(OS_WIN)  | 
26  |  | #include "butil/win/scoped_handle.h"  | 
27  |  | #endif  | 
28  |  |  | 
29  |  | namespace butil { | 
30  |  |  | 
31  |  | class FilePath;  | 
32  |  |  | 
33  |  | #if defined(OS_WIN)  | 
34  |  | typedef HANDLE PlatformFile;  | 
35  |  | #elif defined(OS_POSIX)  | 
36  |  | typedef int PlatformFile;  | 
37  |  |  | 
38  |  | #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)  | 
39  |  | typedef struct stat stat_wrapper_t;  | 
40  |  | #else  | 
41  |  | typedef struct stat64 stat_wrapper_t;  | 
42  |  | #endif  | 
43  |  | #endif  // defined(OS_POSIX)  | 
44  |  |  | 
45  |  | // Thin wrapper around an OS-level file.  | 
46  |  | // Note that this class does not provide any support for asynchronous IO, other  | 
47  |  | // than the ability to create asynchronous handles on Windows.  | 
48  |  | //  | 
49  |  | // Note about const: this class does not attempt to determine if the underlying  | 
50  |  | // file system object is affected by a particular method in order to consider  | 
51  |  | // that method const or not. Only methods that deal with member variables in an  | 
52  |  | // obvious non-modifying way are marked as const. Any method that forward calls  | 
53  |  | // to the OS is not considered const, even if there is no apparent change to  | 
54  |  | // member variables.  | 
55  |  | class BUTIL_EXPORT File { | 
56  |  |   MOVE_ONLY_TYPE_FOR_CPP_03(File, RValue)  | 
57  |  |  | 
58  |  |  public:  | 
59  |  |   // FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one  | 
60  |  |   // of the five (possibly combining with other flags) when opening or creating  | 
61  |  |   // a file.  | 
62  |  |   // FLAG_(WRITE|APPEND) are mutually exclusive. This is so that APPEND behavior  | 
63  |  |   // will be consistent with O_APPEND on POSIX.  | 
64  |  |   // FLAG_EXCLUSIVE_(READ|WRITE) only grant exclusive access to the file on  | 
65  |  |   // creation on POSIX; for existing files, consider using Lock().  | 
66  |  |   enum Flags { | 
67  |  |     FLAG_OPEN = 1 << 0,             // Opens a file, only if it exists.  | 
68  |  |     FLAG_CREATE = 1 << 1,           // Creates a new file, only if it does not  | 
69  |  |                                     // already exist.  | 
70  |  |     FLAG_OPEN_ALWAYS = 1 << 2,      // May create a new file.  | 
71  |  |     FLAG_CREATE_ALWAYS = 1 << 3,    // May overwrite an old file.  | 
72  |  |     FLAG_OPEN_TRUNCATED = 1 << 4,   // Opens a file and truncates it, only if it  | 
73  |  |                                     // exists.  | 
74  |  |     FLAG_READ = 1 << 5,  | 
75  |  |     FLAG_WRITE = 1 << 6,  | 
76  |  |     FLAG_APPEND = 1 << 7,  | 
77  |  |     FLAG_EXCLUSIVE_READ = 1 << 8,   // EXCLUSIVE is opposite of Windows SHARE.  | 
78  |  |     FLAG_EXCLUSIVE_WRITE = 1 << 9,  | 
79  |  |     FLAG_ASYNC = 1 << 10,  | 
80  |  |     FLAG_TEMPORARY = 1 << 11,       // Used on Windows only.  | 
81  |  |     FLAG_HIDDEN = 1 << 12,          // Used on Windows only.  | 
82  |  |     FLAG_DELETE_ON_CLOSE = 1 << 13,  | 
83  |  |     FLAG_WRITE_ATTRIBUTES = 1 << 14,  // Used on Windows only.  | 
84  |  |     FLAG_SHARE_DELETE = 1 << 15,      // Used on Windows only.  | 
85  |  |     FLAG_TERMINAL_DEVICE = 1 << 16,   // Serial port flags.  | 
86  |  |     FLAG_BACKUP_SEMANTICS = 1 << 17,  // Used on Windows only.  | 
87  |  |     FLAG_EXECUTE = 1 << 18,           // Used on Windows only.  | 
88  |  |   };  | 
89  |  |  | 
90  |  |   // This enum has been recorded in multiple histograms. If the order of the  | 
91  |  |   // fields needs to change, please ensure that those histograms are obsolete or  | 
92  |  |   // have been moved to a different enum.  | 
93  |  |   //  | 
94  |  |   // FILE_ERROR_ACCESS_DENIED is returned when a call fails because of a  | 
95  |  |   // filesystem restriction. FILE_ERROR_SECURITY is returned when a browser  | 
96  |  |   // policy doesn't allow the operation to be executed.  | 
97  |  |   enum Error { | 
98  |  |     FILE_OK = 0,  | 
99  |  |     FILE_ERROR_FAILED = -1,  | 
100  |  |     FILE_ERROR_IN_USE = -2,  | 
101  |  |     FILE_ERROR_EXISTS = -3,  | 
102  |  |     FILE_ERROR_NOT_FOUND = -4,  | 
103  |  |     FILE_ERROR_ACCESS_DENIED = -5,  | 
104  |  |     FILE_ERROR_TOO_MANY_OPENED = -6,  | 
105  |  |     FILE_ERROR_NO_MEMORY = -7,  | 
106  |  |     FILE_ERROR_NO_SPACE = -8,  | 
107  |  |     FILE_ERROR_NOT_A_DIRECTORY = -9,  | 
108  |  |     FILE_ERROR_INVALID_OPERATION = -10,  | 
109  |  |     FILE_ERROR_SECURITY = -11,  | 
110  |  |     FILE_ERROR_ABORT = -12,  | 
111  |  |     FILE_ERROR_NOT_A_FILE = -13,  | 
112  |  |     FILE_ERROR_NOT_EMPTY = -14,  | 
113  |  |     FILE_ERROR_INVALID_URL = -15,  | 
114  |  |     FILE_ERROR_IO = -16,  | 
115  |  |     // Put new entries here and increment FILE_ERROR_MAX.  | 
116  |  |     FILE_ERROR_MAX = -17  | 
117  |  |   };  | 
118  |  |  | 
119  |  |   // This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.  | 
120  |  |   enum Whence { | 
121  |  |     FROM_BEGIN   = 0,  | 
122  |  |     FROM_CURRENT = 1,  | 
123  |  |     FROM_END     = 2  | 
124  |  |   };  | 
125  |  |  | 
126  |  |   // Used to hold information about a given file.  | 
127  |  |   // If you add more fields to this structure (platform-specific fields are OK),  | 
128  |  |   // make sure to update all functions that use it in file_util_{win|posix}.cc | 
129  |  |   // too, and the ParamTraits<butil::PlatformFileInfo> implementation in  | 
130  |  |   // chrome/common/common_param_traits.cc.  | 
131  |  |   struct BUTIL_EXPORT Info { | 
132  |  |     Info();  | 
133  |  |     ~Info();  | 
134  |  | #if defined(OS_POSIX)  | 
135  |  |     // Fills this struct with values from |stat_info|.  | 
136  |  |     void FromStat(const stat_wrapper_t& stat_info);  | 
137  |  | #endif  | 
138  |  |  | 
139  |  |     // The size of the file in bytes.  Undefined when is_directory is true.  | 
140  |  |     int64_t size;  | 
141  |  |  | 
142  |  |     // True if the file corresponds to a directory.  | 
143  |  |     bool is_directory;  | 
144  |  |  | 
145  |  |     // True if the file corresponds to a symbolic link.  | 
146  |  |     bool is_symbolic_link;  | 
147  |  |  | 
148  |  |     // The last modified time of a file.  | 
149  |  |     butil::Time last_modified;  | 
150  |  |  | 
151  |  |     // The last accessed time of a file.  | 
152  |  |     butil::Time last_accessed;  | 
153  |  |  | 
154  |  |     // The creation time of a file.  | 
155  |  |     butil::Time creation_time;  | 
156  |  |   };  | 
157  |  |  | 
158  |  |   File();  | 
159  |  |  | 
160  |  |   // Creates or opens the given file. This will fail with 'access denied' if the  | 
161  |  |   // |name| contains path traversal ('..') components. | 
162  |  |   File(const FilePath& name, uint32_t flags);  | 
163  |  |  | 
164  |  |   // Takes ownership of |platform_file|.  | 
165  |  |   explicit File(PlatformFile platform_file);  | 
166  |  |  | 
167  |  |   // Creates an object with a specific error_details code.  | 
168  |  |   explicit File(Error error_details);  | 
169  |  |  | 
170  |  |   // Move constructor for C++03 move emulation of this type.  | 
171  |  |   File(RValue other);  | 
172  |  |  | 
173  |  |   ~File();  | 
174  |  |  | 
175  |  |   // Move operator= for C++03 move emulation of this type.  | 
176  |  |   File& operator=(RValue other);  | 
177  |  |  | 
178  |  |   // Creates or opens the given file.  | 
179  |  |   void Initialize(const FilePath& name, uint32_t flags);  | 
180  |  |  | 
181  |  |   // Creates or opens the given file, allowing paths with traversal ('..') | 
182  |  |   // components. Use only with extreme care.  | 
183  |  |   void InitializeUnsafe(const FilePath& name, uint32_t flags);  | 
184  |  |  | 
185  |  |   bool IsValid() const;  | 
186  |  |  | 
187  |  |   // Returns true if a new file was created (or an old one truncated to zero  | 
188  |  |   // length to simulate a new file, which can happen with  | 
189  |  |   // FLAG_CREATE_ALWAYS), and false otherwise.  | 
190  | 0  |   bool created() const { return created_; } | 
191  |  |  | 
192  |  |   // Returns the OS result of opening this file. Note that the way to verify  | 
193  |  |   // the success of the operation is to use IsValid(), not this method:  | 
194  |  |   //   File file(name, flags);  | 
195  |  |   //   if (!file.IsValid())  | 
196  |  |   //     return;  | 
197  | 0  |   Error error_details() const { return error_details_; } | 
198  |  |  | 
199  |  |   PlatformFile GetPlatformFile() const;  | 
200  |  |   PlatformFile TakePlatformFile();  | 
201  |  |  | 
202  |  |   // Destroying this object closes the file automatically.  | 
203  |  |   void Close();  | 
204  |  |  | 
205  |  |   // Changes current position in the file to an |offset| relative to an origin  | 
206  |  |   // defined by |whence|. Returns the resultant current position in the file  | 
207  |  |   // (relative to the start) or -1 in case of error.  | 
208  |  |   int64_t Seek(Whence whence, int64_t offset);  | 
209  |  |  | 
210  |  |   // Reads the given number of bytes (or until EOF is reached) starting with the  | 
211  |  |   // given offset. Returns the number of bytes read, or -1 on error. Note that  | 
212  |  |   // this function makes a best effort to read all data on all platforms, so it  | 
213  |  |   // is not intended for stream oriented files but instead for cases when the  | 
214  |  |   // normal expectation is that actually |size| bytes are read unless there is  | 
215  |  |   // an error.  | 
216  |  |   int Read(int64_t offset, char* data, int size);  | 
217  |  |  | 
218  |  |   // Same as above but without seek.  | 
219  |  |   int ReadAtCurrentPos(char* data, int size);  | 
220  |  |  | 
221  |  |   // Reads the given number of bytes (or until EOF is reached) starting with the  | 
222  |  |   // given offset, but does not make any effort to read all data on all  | 
223  |  |   // platforms. Returns the number of bytes read, or -1 on error.  | 
224  |  |   int ReadNoBestEffort(int64_t offset, char* data, int size);  | 
225  |  |  | 
226  |  |   // Same as above but without seek.  | 
227  |  |   int ReadAtCurrentPosNoBestEffort(char* data, int size);  | 
228  |  |  | 
229  |  |   // Writes the given buffer into the file at the given offset, overwritting any  | 
230  |  |   // data that was previously there. Returns the number of bytes written, or -1  | 
231  |  |   // on error. Note that this function makes a best effort to write all data on  | 
232  |  |   // all platforms.  | 
233  |  |   // Ignores the offset and writes to the end of the file if the file was opened  | 
234  |  |   // with FLAG_APPEND.  | 
235  |  |   int Write(int64_t offset, const char* data, int size);  | 
236  |  |  | 
237  |  |   // Save as above but without seek.  | 
238  |  |   int WriteAtCurrentPos(const char* data, int size);  | 
239  |  |  | 
240  |  |   // Save as above but does not make any effort to write all data on all  | 
241  |  |   // platforms. Returns the number of bytes written, or -1 on error.  | 
242  |  |   int WriteAtCurrentPosNoBestEffort(const char* data, int size);  | 
243  |  |  | 
244  |  |   // Returns the current size of this file, or a negative number on failure.  | 
245  |  |   int64_t GetLength();  | 
246  |  |  | 
247  |  |   // Truncates the file to the given length. If |length| is greater than the  | 
248  |  |   // current size of the file, the file is extended with zeros. If the file  | 
249  |  |   // doesn't exist, |false| is returned.  | 
250  |  |   bool SetLength(int64_t length);  | 
251  |  |  | 
252  |  |   // Flushes the buffers.  | 
253  |  |   bool Flush();  | 
254  |  |  | 
255  |  |   // Updates the file times.  | 
256  |  |   bool SetTimes(Time last_access_time, Time last_modified_time);  | 
257  |  |  | 
258  |  |   // Returns some basic information for the given file.  | 
259  |  |   bool GetInfo(Info* info);  | 
260  |  |  | 
261  |  |   // Attempts to take an exclusive write lock on the file. Returns immediately  | 
262  |  |   // (i.e. does not wait for another process to unlock the file). If the lock  | 
263  |  |   // was obtained, the result will be FILE_OK. A lock only guarantees  | 
264  |  |   // that other processes may not also take a lock on the same file with the  | 
265  |  |   // same API - it may still be opened, renamed, unlinked, etc.  | 
266  |  |   //  | 
267  |  |   // Common semantics:  | 
268  |  |   //  * Locks are held by processes, but not inherited by child processes.  | 
269  |  |   //  * Locks are released by the OS on file close or process termination.  | 
270  |  |   //  * Locks are reliable only on local filesystems.  | 
271  |  |   //  * Duplicated file handles may also write to locked files.  | 
272  |  |   // Windows-specific semantics:  | 
273  |  |   //  * Locks are mandatory for read/write APIs, advisory for mapping APIs.  | 
274  |  |   //  * Within a process, locking the same file (by the same or new handle)  | 
275  |  |   //    will fail.  | 
276  |  |   // POSIX-specific semantics:  | 
277  |  |   //  * Locks are advisory only.  | 
278  |  |   //  * Within a process, locking the same file (by the same or new handle)  | 
279  |  |   //    will succeed.  | 
280  |  |   //  * Closing any descriptor on a given file releases the lock.  | 
281  |  |   Error Lock();  | 
282  |  |  | 
283  |  |   // Unlock a file previously locked.  | 
284  |  |   Error Unlock();  | 
285  |  |  | 
286  | 0  |   bool async() const { return async_; } | 
287  |  |  | 
288  |  | #if defined(OS_WIN)  | 
289  |  |   static Error OSErrorToFileError(DWORD last_error);  | 
290  |  | #elif defined(OS_POSIX)  | 
291  |  |   static Error OSErrorToFileError(int saved_errno);  | 
292  |  | #endif  | 
293  |  |  | 
294  |  |   // Converts an error value to a human-readable form. Used for logging.  | 
295  |  |   static std::string ErrorToString(Error error);  | 
296  |  |  | 
297  |  |  private:  | 
298  |  |   void SetPlatformFile(PlatformFile file);  | 
299  |  |  | 
300  |  | #if defined(OS_WIN)  | 
301  |  |   win::ScopedHandle file_;  | 
302  |  | #elif defined(OS_POSIX)  | 
303  |  |   ScopedFD file_;  | 
304  |  | #endif  | 
305  |  |  | 
306  |  |   Error error_details_;  | 
307  |  |   bool created_;  | 
308  |  |   bool async_;  | 
309  |  | };  | 
310  |  |  | 
311  |  | }  // namespace butil  | 
312  |  |  | 
313  |  | #endif  // BUTIL_FILES_FILE_H_  |