WinFileStream.cpp
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:6k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #if defined(_MSC_VER)
  3. #if !defined(_WINDOWS_) && !defined(_INC_WINDOWS)
  4. #   define WIN32_LEAN_AND_MEAN
  5. # include <windows.h>
  6. #endif
  7. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  8. # pragma once
  9. # pragma warning(push)
  10. # pragma warning(disable: 4267)
  11. #endif
  12. #include <assert.h>
  13. #include "WinFileStream.h"
  14. namespace febird {
  15. WinFileStream::~WinFileStream()
  16. {
  17. if (m_bAutoClose && INVALID_HANDLE_VALUE != m_hFile)
  18. CloseHandle(m_hFile);
  19. }
  20. WinFileStream::WinFileStream(
  21. HANDLE hFile,
  22. bool bAutoClose,
  23. const std::string& strFile
  24. ) : m_hFile(hFile), m_bAutoClose(false), m_strFile(strFile)
  25. {}
  26. WinFileStream::WinFileStream(
  27. LPCSTR szFile,
  28. DWORD dwDesiredAccess,
  29. DWORD dwShareMode,
  30. LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  31. {
  32. if (!open(szFile, dwDesiredAccess, dwShareMode, lpSecurityAttributes))
  33. {
  34. throw OpenFileException(szFile, ErrorText(GetLastError()).c_str());
  35. }
  36. }
  37. WinFileStream::WinFileStream(
  38. LPCSTR szFile,
  39. DWORD dwDesiredAccess,
  40. DWORD dwShareMode,
  41. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  42. DWORD dwCreationDisposition,
  43. DWORD dwFlagsAndAttributes,
  44. HANDLE hTemplateFile)
  45. {
  46. if (!open(szFile, dwDesiredAccess, dwShareMode, lpSecurityAttributes, 
  47. dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile))
  48. {
  49. throw OpenFileException(szFile, ErrorText(GetLastError()).c_str());
  50. }
  51. }
  52. bool WinFileStream::open(
  53. LPCSTR szFile,
  54. DWORD dwDesiredAccess,
  55. DWORD dwShareMode,
  56. LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  57. {
  58. return open(szFile, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
  59. DefaultCreateDisposition(dwDesiredAccess), 0, NULL
  60. );
  61. }
  62. bool WinFileStream::open(
  63. LPCSTR szFile,
  64. DWORD dwDesiredAccess,
  65. DWORD dwShareMode,
  66. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  67. DWORD dwCreationDisposition,
  68. DWORD dwFlagsAndAttributes,
  69. HANDLE hTemplateFile)
  70. {
  71. m_strFile = szFile;
  72. m_hFile = CreateFile(szFile, dwDesiredAccess, dwShareMode,
  73. lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  74. m_bAutoClose = true;
  75. return INVALID_HANDLE_VALUE != m_hFile;
  76. }
  77. void WinFileStream::attach(HANDLE hFile,
  78.    bool bAutoClose,
  79.    const std::string& strFile)
  80. {
  81. assert(INVALID_HANDLE_VALUE == m_hFile);
  82. m_hFile = hFile;
  83. m_bAutoClose = bAutoClose;
  84. m_strFile  = strFile;
  85. }
  86. HANDLE WinFileStream::detach()
  87. {
  88. assert(INVALID_HANDLE_VALUE != m_hFile);
  89. HANDLE hFile = m_hFile;
  90. m_hFile = INVALID_HANDLE_VALUE;
  91. return hFile;
  92. }
  93. size_t WinFileStream::read(void* vbuf, size_t length)
  94. {
  95. assert(INVALID_HANDLE_VALUE != m_hFile);
  96. DWORD nReaded;
  97. if (ReadFile(m_hFile, vbuf, length, &nReaded, 0))
  98. {
  99. return nReaded;
  100. }
  101. throw IOException(ErrorText(GetLastError()).c_str());
  102. }
  103. size_t WinFileStream::write(const void* vbuf, size_t length)
  104. {
  105. assert(INVALID_HANDLE_VALUE != m_hFile);
  106. DWORD nWritten;
  107. if (WriteFile(m_hFile, vbuf, length, &nWritten, 0))
  108. {
  109. return nWritten;
  110. }
  111. throw IOException(ErrorText(GetLastError()).c_str());
  112. }
  113. uint64_t WinFileStream::do_seek(int64_t offset, int origin)
  114. {
  115. assert(INVALID_HANDLE_VALUE != m_hFile);
  116. LONG hi32 = LONG(uint64_t(offset) >> 32);
  117. LONG lo32 = LONG(offset & 0xFFFFFFFF);
  118. lo32 = SetFilePointer(m_hFile, lo32, &hi32, origin);
  119. DWORD err;
  120. if (INVALID_SET_FILE_POINTER == lo32 && (err = GetLastError()) != NO_ERROR)
  121. {
  122. throw IOException(ErrorText(err).c_str());
  123. }
  124. return uint64_t(hi32) << 32 | lo32;
  125. }
  126. void WinFileStream::seek(int64_t offset, int origin)
  127. {
  128. (void)do_seek(offset, origin);
  129. }
  130. uint64_t WinFileStream::tell() const
  131. {
  132. assert(INVALID_HANDLE_VALUE != m_hFile);
  133. LONG hi32 = 0;
  134. LONG lo32 = 0;
  135. lo32 = SetFilePointer(m_hFile, lo32, &hi32, FILE_CURRENT);
  136. DWORD err;
  137. if (INVALID_SET_FILE_POINTER == lo32 && (err = GetLastError()) != NO_ERROR)
  138. {
  139. throw IOException(ErrorText(err).c_str());
  140. }
  141. return uint64_t(hi32) << 32 | lo32;
  142. }
  143. void WinFileStream::flush()
  144. {
  145. assert(INVALID_HANDLE_VALUE != m_hFile);
  146. if (!FlushFileBuffers(m_hFile))
  147. throw IOException(ErrorText(GetLastError()).c_str());
  148. }
  149. void WinFileStream::close()
  150. {
  151. assert(INVALID_HANDLE_VALUE != m_hFile);
  152. CloseHandle(m_hFile);
  153. }
  154. uint64_t WinFileStream::size()
  155. {
  156. assert(INVALID_HANDLE_VALUE != m_hFile);
  157. uint32_t hi32;
  158. uint32_t lo32 = GetFileSize(m_hFile, &hi32);
  159. DWORD    err;
  160. if (INVALID_FILE_SIZE == lo32 && NO_ERROR != (err = GetLastError()))
  161. {
  162. throw IOException(ErrorText(err).c_str());
  163. }
  164. return uint64_t(hi32) << 32 | lo32;
  165. }
  166. void WinFileStream::setEof(uint64_t newSize)
  167. {
  168. assert(INVALID_HANDLE_VALUE != m_hFile);
  169. uint64_t oldPos = do_seek(newSize, FILE_BEGIN);
  170. BOOL bRet = SetEndOfFile(m_hFile);
  171. seek(oldPos, FILE_BEGIN);
  172. if (!bRet)
  173. throw IOException(ErrorText(GetLastError()).c_str());
  174. }
  175. DWORD WinFileStream::DefaultCreateDisposition(DWORD dwDesiredAccess) const
  176. {
  177. if (dwDesiredAccess & (GENERIC_READ|GENERIC_WRITE))
  178. {
  179. return OPEN_ALWAYS;
  180. }
  181. else if (dwDesiredAccess & GENERIC_READ)
  182. {
  183. return OPEN_EXISTING;
  184. }
  185. else if (dwDesiredAccess & GENERIC_WRITE)
  186. {
  187. return CREATE_ALWAYS;
  188. }
  189. else
  190. {
  191. return OPEN_ALWAYS;
  192. }
  193. }
  194. std::string WinFileStream::ErrorText(DWORD errCode) const
  195. {
  196. HLOCAL hLocal = NULL;
  197. DWORD dwTextLength = FormatMessage(
  198. FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER,
  199. NULL,
  200. errCode,
  201. 0, //MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
  202. (LPTSTR)&hLocal,
  203. 0,
  204. NULL
  205. );
  206. std::string strText = "file: "" + m_strFile + "" error: " + (LPCSTR)LocalLock(hLocal);
  207. LocalFree(hLocal);
  208. return strText;
  209. }
  210. }
  211. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  212. # pragma warning(pop)
  213. #endif
  214. #endif