diff options
-rw-r--r-- | base/file_util.h | 7 | ||||
-rw-r--r-- | base/file_util_posix.cc | 4 | ||||
-rw-r--r-- | base/file_util_win.cc | 12 | ||||
-rw-r--r-- | chrome/common/important_file_writer.cc | 2 |
4 files changed, 24 insertions, 1 deletions
diff --git a/base/file_util.h b/base/file_util.h index a3c9a6e..c51e1a0 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -160,6 +160,13 @@ bool Move(const FilePath& from_path, const FilePath& to_path); // Deprecated temporary compatibility function. bool Move(const std::wstring& from_path, const std::wstring& to_path); +// Renames file |from_path| to |to_path|. Both paths must be on the same +// volume, or the function will fail. Destination file will be created +// if it doesn't exist. Prefer this function over Move when dealing with +// temporary files. On Windows it preserves attributes of the target file. +// Returns true on success. +bool ReplaceFile(const FilePath& from_path, const FilePath& to_path); + // Copies a single file. Use CopyDirectory to copy directories. bool CopyFile(const FilePath& from_path, const FilePath& to_path); // Deprecated temporary compatibility function. diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 96c1c17..5d44ca3 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -168,6 +168,10 @@ bool Move(const FilePath& from_path, const FilePath& to_path) { return true; } +bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) { + return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0); +} + bool CopyDirectory(const FilePath& from_path, const FilePath& to_path, bool recursive) { diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 8964fbf..77247a4 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -116,6 +116,18 @@ bool Move(const FilePath& from_path, const FilePath& to_path) { return false; } +bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) { + // Make sure that the target file exists. + HANDLE target_file = ::CreateFile(to_path.value().c_str(), 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL); + if (target_file != INVALID_HANDLE_VALUE) + ::CloseHandle(target_file); + return ::ReplaceFile(to_path.value().c_str(), from_path.value().c_str(), + NULL, 0, NULL, NULL) ? true : false; +} + bool CopyFile(const FilePath& from_path, const FilePath& to_path) { // NOTE: I suspect we could support longer paths, but that would involve // analyzing all our usage of files. diff --git a/chrome/common/important_file_writer.cc b/chrome/common/important_file_writer.cc index 03e138c..86a7b7d 100644 --- a/chrome/common/important_file_writer.cc +++ b/chrome/common/important_file_writer.cc @@ -55,7 +55,7 @@ class WriteToDiskTask : public Task { return; } - if (file_util::Move(tmp_file_path, path_)) { + if (file_util::ReplaceFile(tmp_file_path, path_)) { LogSuccess(); return; } |