244 lines
5.7 KiB
C++
244 lines
5.7 KiB
C++
![]() |
// Copyright (c) 2011, NetEase Inc. All rights reserved.
|
|||
|
//
|
|||
|
// Author: rl
|
|||
|
// Date: 2011/6/12
|
|||
|
//
|
|||
|
// Modified by wrt(guangguang)
|
|||
|
// Date: 2013/9/17
|
|||
|
//
|
|||
|
// Utilities for file and filepath operation
|
|||
|
|
|||
|
#include "base/file/file_util.h"
|
|||
|
#include <memory>
|
|||
|
#include "base/util/string_util.h"
|
|||
|
#include "base/memory/deleter.h"
|
|||
|
|
|||
|
#if defined(OS_POSIX)
|
|||
|
#include <sys/stat.h>
|
|||
|
#include <dirent.h>
|
|||
|
#include <errno.h>
|
|||
|
#endif // OS_POSIX
|
|||
|
|
|||
|
namespace nbase
|
|||
|
{
|
|||
|
|
|||
|
#if defined(OS_POSIX)
|
|||
|
const PathChar kEndChar = '\0';
|
|||
|
const PathChar kFilePathSeparators[] = "/";
|
|||
|
const PathChar kFilePathCurrentDirectory[] = ".";
|
|||
|
const PathChar kFilePathParentDirectory[] = "..";
|
|||
|
const PathChar kFilePathExtensionSeparator = '.';
|
|||
|
#elif defined(OS_WIN)
|
|||
|
const PathChar kEndChar = L'\0';
|
|||
|
const PathChar kFilePathSeparators[] = L"\\/";
|
|||
|
const PathChar kFilePathCurrentDirectory[] = L".";
|
|||
|
const PathChar kFilePathParentDirectory[] = L"..";
|
|||
|
const PathChar kFilePathExtensionSeparator = L'.';
|
|||
|
#endif // OS_WIN
|
|||
|
|
|||
|
bool IsFilePathSeparator(const PathChar separator)
|
|||
|
{
|
|||
|
if (separator == kEndChar)
|
|||
|
return false;
|
|||
|
|
|||
|
size_t len = sizeof(kFilePathSeparators)/sizeof(PathChar);
|
|||
|
for (size_t i = 0; i < len; i++)
|
|||
|
{
|
|||
|
if (separator == kFilePathSeparators[i])
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool IsFilePathSeparator(const PathString &separator)
|
|||
|
{
|
|||
|
if (separator.empty())
|
|||
|
return false;
|
|||
|
PathChar c = separator[0];
|
|||
|
return IsFilePathSeparator(c);
|
|||
|
}
|
|||
|
|
|||
|
bool FilePathExtension(const PathString &filepath_in, PathString &extension_out)
|
|||
|
{
|
|||
|
if (filepath_in.size() == 0)
|
|||
|
return false;
|
|||
|
bool ret = false;
|
|||
|
PathString file_name;
|
|||
|
if (FilePathApartFileName(filepath_in, file_name))
|
|||
|
{
|
|||
|
size_t pos = file_name.rfind(kFilePathExtensionSeparator);
|
|||
|
if (pos != PathString::npos)
|
|||
|
{
|
|||
|
extension_out = file_name.substr(pos, PathString::npos);
|
|||
|
ret = true;
|
|||
|
}
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
bool FilePathApartDirectory(const PathString &filepath_in,
|
|||
|
PathString &directory_out)
|
|||
|
{
|
|||
|
size_t index = filepath_in.size() - 1;
|
|||
|
if (index <= 0 || filepath_in.size() == 0)
|
|||
|
return false;
|
|||
|
for (; index != 0; index--)
|
|||
|
{
|
|||
|
if (IsFilePathSeparator(filepath_in[index]))
|
|||
|
{
|
|||
|
if (index == filepath_in.size() - 1)
|
|||
|
directory_out = filepath_in;
|
|||
|
else
|
|||
|
directory_out = filepath_in.substr(0, index + 1);
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
bool FilePathApartFileName(const PathString &filepath_in,
|
|||
|
PathString &filename_out)
|
|||
|
{
|
|||
|
if (filepath_in.size() == 0)
|
|||
|
return false;
|
|||
|
bool ret = true;
|
|||
|
size_t separator_pos = PathString::npos;
|
|||
|
size_t separators_count = sizeof(kFilePathSeparators) / sizeof(PathChar);
|
|||
|
for (size_t index = 0; index < separators_count; index++)
|
|||
|
{
|
|||
|
separator_pos = filepath_in.rfind(kFilePathSeparators[index]);
|
|||
|
if (separator_pos != PathString::npos)
|
|||
|
break;
|
|||
|
}
|
|||
|
if (separator_pos++ != PathString::npos && separator_pos < filepath_in.size())
|
|||
|
filename_out = filepath_in.substr(separator_pos);
|
|||
|
else if (separator_pos >= filepath_in.size())
|
|||
|
ret = false;
|
|||
|
else
|
|||
|
filename_out = filepath_in;
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
template<typename CharType>
|
|||
|
bool ParsePathComponentsT(const CharType *path,
|
|||
|
const CharType *seperators,
|
|||
|
std::list<std::basic_string<CharType> > &components)
|
|||
|
{
|
|||
|
components.clear();
|
|||
|
if (path == NULL)
|
|||
|
return false;
|
|||
|
const CharType *prev = NULL;
|
|||
|
const CharType *next = path;
|
|||
|
const CharType *c;
|
|||
|
while (*next)
|
|||
|
{
|
|||
|
prev = next;
|
|||
|
// find the first seperator
|
|||
|
for (;;)
|
|||
|
{
|
|||
|
for (c = seperators; *c && *next != *c; c++);
|
|||
|
if (*c || !*next)
|
|||
|
break;
|
|||
|
next++;
|
|||
|
}
|
|||
|
components.push_back(std::basic_string<CharType>(prev, next - prev));
|
|||
|
if (*next)
|
|||
|
components.back().push_back(*seperators);
|
|||
|
// skip duplicated seperators
|
|||
|
for (++next;;)
|
|||
|
{
|
|||
|
for (c = seperators; *c && *next != *c; c++);
|
|||
|
if (!*c)
|
|||
|
break;
|
|||
|
next++;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool ParsePathComponents(const PathChar *path,
|
|||
|
std::list<PathString> &components)
|
|||
|
{
|
|||
|
return ParsePathComponentsT<PathChar>(path,
|
|||
|
kFilePathSeparators,
|
|||
|
components);
|
|||
|
}
|
|||
|
|
|||
|
bool IsDirectoryComponent(const PathString &component)
|
|||
|
{
|
|||
|
if (component.empty())
|
|||
|
return false;
|
|||
|
#if defined(OS_WIN)
|
|||
|
return *component.rbegin() == kFilePathSeparators[0] ||
|
|||
|
*component.rbegin() == kFilePathSeparators[1];
|
|||
|
#else
|
|||
|
return *component.rbegin() == kFilePathSeparators[0];
|
|||
|
#endif // OS_WIN
|
|||
|
}
|
|||
|
|
|||
|
bool FilePathCompose(const PathString &directory_in,
|
|||
|
const PathString &filename_in,
|
|||
|
PathString &filepath_out)
|
|||
|
{
|
|||
|
PathString directory;
|
|||
|
if (!FilePathApartDirectory(directory_in, directory))
|
|||
|
return false;
|
|||
|
filepath_out = directory + filename_in;
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool FilePathIsExist(const PathString &filepath_in, bool is_directory)
|
|||
|
{
|
|||
|
return FilePathIsExist((const PathChar *)filepath_in.c_str(), is_directory);
|
|||
|
}
|
|||
|
|
|||
|
FILE* OpenFile(const PathString &filepath, const PathChar *mode)
|
|||
|
{
|
|||
|
return OpenFile(filepath.c_str(), mode);
|
|||
|
}
|
|||
|
|
|||
|
bool CloseFile(FILE *file)
|
|||
|
{
|
|||
|
if (NULL == file)
|
|||
|
return true;
|
|||
|
return fclose(file) == 0;
|
|||
|
}
|
|||
|
|
|||
|
int ReadFile(const PathString &filepath, void *data_out, size_t size)
|
|||
|
{
|
|||
|
return ReadFile(filepath.c_str(), data_out, size);
|
|||
|
}
|
|||
|
|
|||
|
int WriteFile(const PathString &filepath, const std::string &data)
|
|||
|
{
|
|||
|
return WriteFile(filepath.c_str(), data.c_str(), data.size());
|
|||
|
}
|
|||
|
|
|||
|
bool ReadFileToString(const PathString &filepath, std::string &out)
|
|||
|
{
|
|||
|
std::unique_ptr<FILE, nbase::DeleterFileClose> file;
|
|||
|
#if defined(OS_WIN)
|
|||
|
file.reset(OpenFile(filepath.c_str(), L"rb"));
|
|||
|
#else
|
|||
|
file.reset(OpenFile(filepath.c_str(), "rb"));
|
|||
|
#endif
|
|||
|
|
|||
|
if (!file)
|
|||
|
return false;
|
|||
|
|
|||
|
size_t file_size = (size_t)GetFileSize(filepath);
|
|||
|
if (file_size > std::numeric_limits<size_t>::max()) //x64<36><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>£<EFBFBD>size_t<5F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵתΪint64_t<5F><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD>
|
|||
|
return false; // Too large
|
|||
|
|
|||
|
bool read_ok = true;
|
|||
|
out.resize(file_size);
|
|||
|
if (!out.empty()) {
|
|||
|
read_ok = fread(&out[0], 1, out.size(), file.get()) == out.size();
|
|||
|
}
|
|||
|
|
|||
|
return read_ok;
|
|||
|
}
|
|||
|
|
|||
|
} // namespace nbase
|