// Copyright (c) 2011, NetEase Inc. All rights reserved. // // Author: rl // Date: 2011/6/12 // // Modified by wrt(guangguang) // Date: 2013/9/5 // // Utilities for file and filepath operation #include "file_util.h" #include "base/util/string_util.h" #if defined(OS_WIN) #include #include "base/win32/scoped_win_handle.h" namespace nbase { bool FilePathCurrentDirectory(PathString &directory_out) { PathChar directory[MAX_PATH]; directory[0] = 0; DWORD len = ::GetCurrentDirectoryW(MAX_PATH, directory); if (len == 0 || len > MAX_PATH) { return false; } directory_out = directory; directory_out.append(1, kFilePathSeparators[0]); return true; } bool FilePathIsExist(const PathChar *filepath_in, bool is_directory) { const DWORD file_attr = ::GetFileAttributesW(filepath_in); if (file_attr != INVALID_FILE_ATTRIBUTES) { if (is_directory) return (file_attr & FILE_ATTRIBUTE_DIRECTORY) != 0; else return true; } return false; } bool CreateDirectory(const PathString& full_path) { return CreateDirectory(full_path.c_str()); } bool CreateDirectory(const PathChar* full_path) { if (full_path == nullptr) return false; if (FilePathIsExist(full_path, true)) return true; std::list subpaths; ParsePathComponents(full_path, subpaths); if (subpaths.empty()) return false; // Collect a list of all parent directories. auto curr = subpaths.begin(); for (auto prev = curr++; curr != subpaths.end(); curr++) { *curr = *prev + *curr; prev = curr; } // Iterate through the parents and create the missing ones. for (auto i = subpaths.begin(); i != subpaths.end(); ++i) { if (FilePathIsExist(i->c_str(), true)) continue; if (!::CreateDirectoryW(i->c_str(), NULL)) { DWORD error = ::GetLastError(); if (error == ERROR_ALREADY_EXISTS && FilePathIsExist(i->c_str(), true)) { continue; } return false; } } return true; } FILE* OpenFile(const PathChar *filepath, const PathChar *mode) { return _wfsopen(filepath, mode, _SH_DENYNO); } int ReadFile(const PathChar *filepath, void *data_out, size_t size) { win32::ScopedWinHandle file(CreateFileW(filepath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL)); if (!file) return -1; DWORD read; if (::ReadFile(file, data_out, (DWORD)size, &read, NULL) && static_cast(read) == size) return read; return -1; } int WriteFile(const PathChar *filepath, const void *data, size_t size) { win32::ScopedWinHandle file(CreateFileW(filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)); if (!file) return -1; DWORD written; BOOL result = ::WriteFile(file, data, (DWORD)size, &written, NULL); if (result && static_cast(written) == size) return written; return -1; } bool CopyFile(const PathString &from_path, const PathString &to_path) { if (from_path.size() >= MAX_PATH || to_path.size() >= MAX_PATH) { return false; } return (::CopyFileW(from_path.c_str(), to_path.c_str(), false) != 0); } bool DeleteFile(const PathString &filepath) { if (::DeleteFileW(filepath.c_str()) != 0) return true; return false; } int64_t GetFileSize(const PathString &filepath) { WIN32_FIND_DATAW file_data; HANDLE file = FindFirstFileW(filepath.c_str(), &file_data); if (file == INVALID_HANDLE_VALUE) return -1; LARGE_INTEGER li = { file_data.nFileSizeLow, (LONG)file_data.nFileSizeHigh }; FindClose(file); return li.QuadPart; } } // namespace nbase #endif // OS_WIN