Utility.File.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <string>
  2. #include <type_traits>
  3. #include "String.WString.hpp"
  4. #include "WStringArray.hpp"
  5. #include "String.StringView.hpp"
  6. #pragma once
  7. //namespace eFile = ECOM::Utility::File;
  8. namespace ECOM { namespace Utility { namespace File
  9. {
  10. // using PCXSTR = const char *;
  11. // using PCWSTR = const wchar_t *;
  12. using PCXSTR = CV_String &;
  13. using PCWSTR = CV_WString &;
  14. bool IsExist (PCXSTR FileName);
  15. bool IsExist (PCWSTR FileName);
  16. size_t Length (PCXSTR FileName);
  17. size_t Length (PCWSTR FileName);
  18. bool Delete (PCXSTR FileName);
  19. bool Delete (PCWSTR FileName);
  20. bool ForceDelete (PCXSTR FileName);
  21. bool ForceDelete (PCWSTR FileName);
  22. bool Rename (PCXSTR fromFileName, PCXSTR toFileName);
  23. bool Rename (PCWSTR fromFileName, PCWSTR toFileName);
  24. bool CreateDir (PCXSTR DirName);
  25. bool CreateDir (PCWSTR DirName);
  26. // 返回目录名
  27. eSTR::DString GetParent (PCXSTR FileName);
  28. eSTR::WString GetParent (PCWSTR FileName);
  29. } } }
  30. namespace ECOM { namespace Utility { namespace File
  31. {
  32. inline bool IsExist (PCXSTR FileName)
  33. {
  34. WIN32_FIND_DATAA FindData;
  35. lstrcpyA (FindData.cFileName, FileName);
  36. auto hContext = ::FindFirstFileA (FileName, &FindData);
  37. if (hContext == INVALID_HANDLE_VALUE)
  38. return false;
  39. ::FindClose (hContext);
  40. return true;
  41. }
  42. inline bool IsExist (PCWSTR FileName)
  43. {
  44. WIN32_FIND_DATAW FindData;
  45. wcsncpy_s (FindData.cFileName, FileName, sizeof (FindData.cFileName) / sizeof (wchar_t));
  46. HANDLE hContext = ::FindFirstFileW (FileName, &FindData);
  47. if (hContext == INVALID_HANDLE_VALUE)
  48. return false;
  49. ::FindClose (hContext);
  50. return true;
  51. }
  52. inline bool Delete (PCXSTR FileName)
  53. {
  54. auto rc = ::DeleteFileA (FileName);
  55. return (rc);
  56. }
  57. inline bool Delete (PCWSTR FileName)
  58. {
  59. auto rc = ::DeleteFileW (FileName);
  60. return (rc);
  61. }
  62. inline bool ForceDelete (PCXSTR FileName)
  63. {
  64. ::SetFileAttributesA (FileName, FILE_ATTRIBUTE_NORMAL);
  65. auto rc = ::DeleteFileA (FileName);
  66. return (rc);
  67. }
  68. inline bool ForceDelete (PCWSTR FileName)
  69. {
  70. ::SetFileAttributesW (FileName, FILE_ATTRIBUTE_NORMAL);
  71. auto rc = ::DeleteFileW (FileName);
  72. return (rc);
  73. }
  74. // 如果 toFileName 有子目录, 应该让调用者来创建子目录
  75. inline bool Rename (PCXSTR fromFileName, PCXSTR toFileName)
  76. {
  77. // auto DirName = GetParent (toFileName);
  78. // CreateDir (DirName);
  79. auto rc = ::MoveFileA (fromFileName, toFileName);
  80. return (rc);
  81. }
  82. inline bool Rename (PCWSTR fromFileName, PCWSTR toFileName)
  83. {
  84. // auto DirName = GetParent (toFileName);
  85. // CreateDir (DirName);
  86. auto rc = ::MoveFileW (fromFileName, toFileName);
  87. return (rc);
  88. }
  89. inline size_t Length (PCXSTR FileName)
  90. {
  91. auto H = CreateFileA (FileName, READ_CONTROL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  92. if (H == INVALID_HANDLE_VALUE)
  93. return 0;
  94. LARGE_INTEGER large;
  95. auto rc = GetFileSizeEx (H, &large);
  96. CloseHandle (H);
  97. return large.QuadPart;
  98. }
  99. inline size_t Length (PCWSTR FileName)
  100. {
  101. auto H = CreateFileW (FileName, READ_CONTROL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
  102. if (H == INVALID_HANDLE_VALUE)
  103. return 0;
  104. LARGE_INTEGER large;
  105. auto rc = GetFileSizeEx (H, &large);
  106. CloseHandle (H);
  107. return large.QuadPart;
  108. }
  109. inline constexpr eSTR::DStringView _ToSV (const char * S)
  110. {
  111. return eSTR::DStringView (S);
  112. }
  113. inline constexpr eSTR::WStringView _ToSV (const wchar_t * S)
  114. {
  115. return eSTR::WStringView (S);
  116. }
  117. template <typename T>
  118. bool _CreateDir (const T & DirName, const T & strStopDirName, std::function <void (const T &)> fun)
  119. {
  120. /// 删除 StopDirName 尾部的反斜杠
  121. T StopDirName (strStopDirName);
  122. int len = StopDirName.GetLength ();
  123. bool bFound = (StopDirName.GetAt (len - 1) == '\\');
  124. if (bFound)
  125. {
  126. int At = len - 1;
  127. for (;; At--)
  128. if (StopDirName.GetAt (At) != '\\')
  129. break;
  130. StopDirName = StopDirName.Left (At+1);
  131. }
  132. ///
  133. T dd (DirName);
  134. std::vector <T> m_arr; // DString Array to hold Directory Structures
  135. T tem; // Temporary DString Object
  136. for (int Index = 0; Index<dd.GetLength (); Index++) // Parse the supplied DString Directory String
  137. {
  138. if (dd.GetAt (Index) == '\\') // if the Charachter is a \
  139. {
  140. m_arr.push_back (tem); // if the Character is a \ Add the Temp String to the DString Array
  141. tem += _ToSV ("\\"); // Now add the \ to the temp string
  142. }
  143. else
  144. if (dd.GetAt (Index) == '/') // if the Charachter is a /
  145. {
  146. m_arr.push_back (tem); // if the Character is a / Add the Temp String to the DString Array
  147. tem += _ToSV ("/"); // Now add the \ to the temp string
  148. }
  149. else
  150. tem += dd.GetAt (Index); // else add character to Temp String
  151. if (Index == dd.GetLength () - 1) // If we reached the end of the file add the remaining string
  152. if ((dd [Index] != '\\') && (dd [Index] != '/'))
  153. m_arr.push_back (tem);
  154. }
  155. for (auto & Dir : m_arr)
  156. {
  157. if (StopDirName.GetLength ())
  158. if (Dir.CompareNoCase (StopDirName) < 0)
  159. continue;
  160. // CreateDirectory (Dir, nullptr);
  161. fun (Dir);
  162. }
  163. return true;
  164. }
  165. inline bool CreateDir (const eSTR::DString & DirName, const eSTR::DString & StopDirName)
  166. {
  167. return _CreateDir <eSTR::DString> (DirName, StopDirName, [ ] (const eSTR::DString & Dir)
  168. {
  169. CreateDirectoryA (Dir, nullptr);
  170. });
  171. }
  172. inline bool CreateDir (const eSTR::WString & DirName, const eSTR::WString & StopDirName)
  173. {
  174. return _CreateDir <eSTR::WString> (DirName, StopDirName, [ ] (const eSTR::WString & Dir)
  175. {
  176. CreateDirectoryW (Dir, nullptr);
  177. });
  178. }
  179. inline bool CreateDir (const eSTR::DString & DirName)
  180. {
  181. return CreateDir (DirName, eSTR::DString ());
  182. }
  183. inline bool CreateDir (const eSTR::WString & DirName)
  184. {
  185. return CreateDir (DirName, eSTR::WString ());
  186. }
  187. inline bool CreateDir (PCXSTR DirName)
  188. {
  189. return CreateDir (eSTR::DString{ DirName }, eSTR::DString ());
  190. }
  191. inline bool CreateDir (PCWSTR DirName)
  192. {
  193. return CreateDir (eSTR::WString{ DirName }, eSTR::WString ());
  194. }
  195. inline eSTR::DString GetParent (PCXSTR FileName)
  196. {
  197. eSTR::DString path (FileName);
  198. auto pos = path.ReverseFind ('\\');
  199. eSTR::DString parent;
  200. if (pos > 0)
  201. parent = path.Mid (0, pos);
  202. return parent;
  203. }
  204. inline eSTR::WString GetParent (PCWSTR FileName)
  205. {
  206. eSTR::WString path (FileName);
  207. auto pos = path.ReverseFind ('\\');
  208. eSTR::WString parent;
  209. if (pos > 0)
  210. parent = path.Mid (0, pos);
  211. return parent;
  212. }
  213. }}}