diff options
author | loislo@chromium.org <loislo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-29 12:57:10 +0000 |
---|---|---|
committer | loislo@chromium.org <loislo@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-29 12:57:10 +0000 |
commit | 891128f4847bfb32e10604ced9a3b93c0272a80d (patch) | |
tree | 001b3799eda821b47e2efa01a8412a194377fc8b /base | |
parent | 19bacfe41d03eede36a797ea37e8c8c2a477e995 (diff) | |
download | chromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.zip chromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.tar.gz chromium_src-891128f4847bfb32e10604ced9a3b93c0272a80d.tar.bz2 |
AppendToFile implementation.
DevTools wants to save very big files like HeapSnapshots.
It is not possible at the moment because the file can be about ~6Gb.
BUG=none
TEST=FileUtilTest.AppendToFile
Review URL: http://codereview.chromium.org/10263003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134492 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/file_util.h | 4 | ||||
-rw-r--r-- | base/file_util_posix.cc | 12 | ||||
-rw-r--r-- | base/file_util_unittest.cc | 28 | ||||
-rw-r--r-- | base/file_util_win.cc | 32 |
4 files changed, 76 insertions, 0 deletions
diff --git a/base/file_util.h b/base/file_util.h index b6e634d..1eac1ca 100644 --- a/base/file_util.h +++ b/base/file_util.h @@ -378,6 +378,10 @@ BASE_EXPORT int WriteFile(const FilePath& filename, const char* data, int size); // Append the data to |fd|. Does not close |fd| when done. BASE_EXPORT int WriteFileDescriptor(const int fd, const char* data, int size); #endif +// Append the given buffer into the file. Returns the number of bytes written, +// or -1 on error. +BASE_EXPORT int AppendToFile(const FilePath& filename, + const char* data, int size); // Gets the current working directory for the process. BASE_EXPORT bool GetCurrentDirectory(FilePath* path); diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc index 00c96fd..f1113d5 100644 --- a/base/file_util_posix.cc +++ b/base/file_util_posix.cc @@ -664,6 +664,18 @@ int WriteFileDescriptor(const int fd, const char* data, int size) { return bytes_written_total; } +int AppendToFile(const FilePath& filename, const char* data, int size) { + base::ThreadRestrictions::AssertIOAllowed(); + int fd = HANDLE_EINTR(open(filename.value().c_str(), O_WRONLY | O_APPEND)); + if (fd < 0) + return -1; + + int bytes_written = WriteFileDescriptor(fd, data, size); + if (int ret = HANDLE_EINTR(close(fd)) < 0) + return ret; + return bytes_written; +} + // Gets the current working directory for the process. bool GetCurrentDirectory(FilePath* dir) { // getcwd can return ENOENT, which implies it checks against the disk. diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc index 30db82c..ea8918b 100644 --- a/base/file_util_unittest.cc +++ b/base/file_util_unittest.cc @@ -1790,6 +1790,34 @@ TEST_F(FileUtilTest, FileEnumeratorTest) { // (we don't care what). } +TEST_F(FileUtilTest, AppendToFile) { + FilePath data_dir = + temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); + + // Create a fresh, empty copy of this directory. + if (file_util::PathExists(data_dir)) { + ASSERT_TRUE(file_util::Delete(data_dir, true)); + } + ASSERT_TRUE(file_util::CreateDirectory(data_dir)); + + // Create a fresh, empty copy of this directory. + if (file_util::PathExists(data_dir)) { + ASSERT_TRUE(file_util::Delete(data_dir, true)); + } + ASSERT_TRUE(file_util::CreateDirectory(data_dir)); + FilePath foobar(data_dir.Append(FILE_PATH_LITERAL("foobar.txt"))); + + std::string data("hello"); + EXPECT_EQ(-1, file_util::AppendToFile(foobar, data.c_str(), data.length())); + EXPECT_EQ(static_cast<int>(data.length()), + file_util::WriteFile(foobar, data.c_str(), data.length())); + EXPECT_EQ(static_cast<int>(data.length()), + file_util::AppendToFile(foobar, data.c_str(), data.length())); + + const std::wstring read_content = ReadTextFile(foobar); + EXPECT_EQ(L"hellohello", read_content); +} + TEST_F(FileUtilTest, Contains) { FilePath data_dir = temp_dir_.path().Append(FILE_PATH_LITERAL("FilePathTest")); diff --git a/base/file_util_win.cc b/base/file_util_win.cc index 7d28f5c..e9f9def 100644 --- a/base/file_util_win.cc +++ b/base/file_util_win.cc @@ -722,6 +722,38 @@ int WriteFile(const FilePath& filename, const char* data, int size) { return -1; } +int AppendToFile(const FilePath& filename, const char* data, int size) { + base::ThreadRestrictions::AssertIOAllowed(); + base::win::ScopedHandle file(CreateFile(filename.value().c_str(), + FILE_APPEND_DATA, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL)); + if (!file) { + DLOG(WARNING) << "CreateFile failed for path " << filename.value() + << " error code=" << GetLastError(); + return -1; + } + + DWORD written; + BOOL result = ::WriteFile(file, data, size, &written, NULL); + if (result && static_cast<int>(written) == size) + return written; + + if (!result) { + // WriteFile failed. + DLOG(WARNING) << "writing file " << filename.value() + << " failed, error code=" << GetLastError(); + } else { + // Didn't write all the bytes. + DLOG(WARNING) << "wrote" << written << " bytes to " + << filename.value() << " expected " << size; + } + return -1; +} + // Gets the current working directory for the process. bool GetCurrentDirectory(FilePath* dir) { base::ThreadRestrictions::AssertIOAllowed(); |