FileManipulation.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #pragma once
  2. #include <windows.h>
  3. #include "ExceptionSystem.hpp"
  4. #include "ResourceObject.hpp"
  5. #undef __BASE_FILE__
  6. #define __BASE_FILE__ TEXT("FileManipulation.hpp")
  7. struct GenericHandleTraits {
  8. using HandleType = HANDLE;
  9. static inline const HandleType InvalidValue = NULL;
  10. static constexpr auto& Releasor = CloseHandle;
  11. };
  12. struct FileHandleTraits {
  13. using HandleType = HANDLE;
  14. static inline const HandleType InvalidValue = INVALID_HANDLE_VALUE;
  15. static constexpr auto& Releasor = CloseHandle;
  16. };
  17. struct MapViewTraits {
  18. using HandleType = PVOID;
  19. static inline const HandleType InvalidValue = NULL;
  20. static constexpr auto& Releasor = UnmapViewOfFile;
  21. };
  22. class FileObject {
  23. private:
  24. ResourceObject<FileHandleTraits> _Obj;
  25. explicit FileObject(HANDLE Handle) noexcept:
  26. _Obj(Handle) {}
  27. public:
  28. static bool IsExist(const TString& FileName) {
  29. DWORD dwAttributes = GetFileAttributes(FileName.c_str());
  30. if (dwAttributes == INVALID_FILE_ATTRIBUTES) {
  31. if (GetLastError() == ERROR_FILE_NOT_FOUND)
  32. return false;
  33. else
  34. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  35. TEXT("GetFileAttributes failed."));
  36. } else {
  37. return (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
  38. }
  39. }
  40. template<typename __ReturnType>
  41. static __ReturnType Create(const TString& FileName, DWORD DesireAccess, DWORD ShareMode) {
  42. static_assert(std::is_same<__ReturnType, FileObject>::value ||
  43. std::is_same<__ReturnType, FileObject*>::value);
  44. HANDLE Handle = ::CreateFile(FileName.c_str(),
  45. DesireAccess,
  46. ShareMode,
  47. NULL,
  48. CREATE_ALWAYS,
  49. FILE_ATTRIBUTE_NORMAL,
  50. NULL);
  51. if (Handle == INVALID_HANDLE_VALUE) {
  52. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  53. TEXT("CreateFile failed."));
  54. }
  55. if constexpr (std::is_same<__ReturnType, FileObject>::value)
  56. return FileObject(Handle);
  57. else
  58. return new FileObject(Handle);
  59. }
  60. template<typename __ReturnType>
  61. static __ReturnType Open(const TString& FileName, DWORD DesireAccess, DWORD ShareMode) {
  62. static_assert(std::is_same<__ReturnType, FileObject>::value ||
  63. std::is_same<__ReturnType, FileObject*>::value);
  64. HANDLE FileHandle = ::CreateFile(FileName.c_str(),
  65. DesireAccess,
  66. ShareMode,
  67. NULL,
  68. OPEN_EXISTING,
  69. FILE_ATTRIBUTE_NORMAL,
  70. NULL);
  71. if (FileHandle == INVALID_HANDLE_VALUE) {
  72. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  73. TEXT("CreateFile failed."));
  74. }
  75. if constexpr (std::is_same<__ReturnType, FileObject>::value)
  76. return FileObject(FileHandle);
  77. else
  78. return new FileObject(FileHandle);
  79. }
  80. HANDLE GetHandle() const noexcept {
  81. return _Obj.Get();
  82. }
  83. UINT64 GetSize() const {
  84. LARGE_INTEGER Val;
  85. if (GetFileSizeEx(_Obj, &Val)) {
  86. return Val.QuadPart;
  87. } else {
  88. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  89. TEXT("GetFileSizeEx failed."));
  90. }
  91. }
  92. void Destroy() {
  93. _Obj.Release();
  94. }
  95. };
  96. class FileMapViewObject {
  97. private:
  98. ResourceObject<GenericHandleTraits> _MapObj;
  99. ResourceObject<MapViewTraits> _ViewObj;
  100. explicit FileMapViewObject(HANDLE MapHandle) noexcept :
  101. _MapObj(MapHandle) {}
  102. public:
  103. template<typename __ReturnType>
  104. static __ReturnType Create(HANDLE FileHandle, DWORD ProtectAttributes) {
  105. static_assert(std::is_same<__ReturnType, FileMapViewObject>::value ||
  106. std::is_same<__ReturnType, FileMapViewObject*>::value);
  107. HANDLE MapHandle = CreateFileMapping(FileHandle,
  108. NULL,
  109. ProtectAttributes,
  110. 0,
  111. 0,
  112. NULL);
  113. if (MapHandle == NULL) {
  114. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  115. TEXT("CreateFileMapping failed."));
  116. }
  117. if constexpr (std::is_same<__ReturnType, FileMapViewObject>::value)
  118. return FileMapViewObject(MapHandle);
  119. else
  120. return new FileMapViewObject(MapHandle);
  121. }
  122. void Map(DWORD DesiredAccess, UINT64 Offset = 0, SIZE_T Size = 0) {
  123. PVOID pView = MapViewOfFile(_MapObj,
  124. DesiredAccess,
  125. static_cast<DWORD>(Offset >> 32),
  126. static_cast<DWORD>(Offset),
  127. Size);
  128. if (pView == NULL) {
  129. throw SystemException(__BASE_FILE__, __LINE__, GetLastError(),
  130. TEXT("MapViewOfFile failed."));
  131. } else {
  132. _ViewObj.TakeOver(pView);
  133. }
  134. }
  135. void Unmap() {
  136. _ViewObj.Release();
  137. }
  138. void Destory() {
  139. Unmap();
  140. _MapObj.Release();
  141. }
  142. template<typename __Type>
  143. __Type* View() const noexcept {
  144. return reinterpret_cast<__Type*>(_ViewObj.Get());
  145. }
  146. template<typename __Type>
  147. const __Type* ConstView() const noexcept {
  148. return reinterpret_cast<__Type*>(_ViewObj.Get());
  149. }
  150. };