2
0

File.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include "File.h"
  2. #include "FileService.h"
  3. #ifndef _XBOX
  4. File::File(const char * _cppFileName, long _cppFileLine)
  5. {
  6. handle = INVALID_HANDLE_VALUE;
  7. #ifndef STOP_DEBUG
  8. cppFileName = _cppFileName;
  9. cppFileLine = _cppFileLine;
  10. #endif
  11. }
  12. File::~File()
  13. {
  14. if(handle != INVALID_HANDLE_VALUE)
  15. {
  16. ::CloseHandle(handle);
  17. handle = INVALID_HANDLE_VALUE;
  18. }
  19. }
  20. //Закрыть файл сообщив об ошибке
  21. void File::ErrorRelease()
  22. {
  23. #ifndef STOP_DEBUG
  24. FileService::object->Error("FileService error: IFile not release (file: %s, line %i)", cppFileName, cppFileLine);
  25. #endif
  26. delete this;
  27. }
  28. //Закрыть файл
  29. void File::Release()
  30. {
  31. {
  32. SingleExClassThread(FileService::object)
  33. FileService::object->DeleteFile(this);
  34. }
  35. delete this;
  36. }
  37. //Открыть файл
  38. bool File::Open(const char * realPath, IFileService_OpenMode mode)
  39. {
  40. dword creation;
  41. dword access = GENERIC_WRITE | GENERIC_READ;
  42. dword share = FILE_SHARE_READ | FILE_SHARE_WRITE;
  43. switch(mode)
  44. {
  45. case file_create_always:
  46. creation = CREATE_ALWAYS;
  47. break;
  48. case file_create_new:
  49. creation = CREATE_NEW;
  50. break;
  51. case file_open_always:
  52. creation = OPEN_ALWAYS;
  53. break;
  54. case file_open_existing:
  55. creation = OPEN_EXISTING;
  56. break;
  57. case file_truncate_existing:
  58. creation = TRUNCATE_EXISTING;
  59. break;
  60. case file_open_existing_for_read:
  61. creation = OPEN_EXISTING;
  62. access = GENERIC_READ;
  63. //share = FILE_SHARE_READ;
  64. break;
  65. default:
  66. Assert(false);
  67. }
  68. handle = ::CreateFile(realPath, access, share, null, creation, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, null);
  69. if(handle == INVALID_HANDLE_VALUE)
  70. {
  71. const char * fileName = string::GetFileName(realPath);
  72. long len = fileName - realPath + 1;
  73. array<char> filePath(_FL_);
  74. filePath.AddElements(len);
  75. memcpy(filePath.GetBuffer(), realPath, len);
  76. filePath[len - 1] = 0;
  77. FileService::object->CreateFolder(filePath.GetBuffer());
  78. if(share & FILE_SHARE_WRITE)
  79. {
  80. dword attributes = ::GetFileAttributes(realPath);
  81. if(attributes != INVALID_FILE_ATTRIBUTES)
  82. {
  83. if(attributes & FILE_ATTRIBUTE_READONLY)
  84. {
  85. attributes &= ~FILE_ATTRIBUTE_READONLY;
  86. ::SetFileAttributes(realPath, attributes);
  87. }
  88. }
  89. }
  90. handle = ::CreateFile(realPath, access, share, null, creation, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, null);
  91. if(handle == INVALID_HANDLE_VALUE)
  92. {
  93. dword errorCode = ::GetLastError();
  94. return false;
  95. }
  96. }
  97. return true;
  98. }
  99. //Прочитать данные, возвращает количество прочитаных байт
  100. dword File::Read(void * buffer, dword size)
  101. {
  102. if(!size) return 0;
  103. Assert(buffer);
  104. Assert(handle != INVALID_HANDLE_VALUE);
  105. DWORD readBytes = 0;
  106. if(::ReadFile(handle, buffer, size, &readBytes, null))
  107. {
  108. return readBytes;
  109. }
  110. return 0;
  111. }
  112. //Записать данные, возвращает количество записаных байт
  113. dword File::Write(const void * buffer, dword size)
  114. {
  115. if(!size) return 0;
  116. Assert(buffer);
  117. Assert(handle != INVALID_HANDLE_VALUE);
  118. DWORD writeBytes = 0;
  119. if(::WriteFile(handle, buffer, size, &writeBytes, null))
  120. {
  121. return writeBytes;
  122. }
  123. return 0;
  124. }
  125. //Установить текущую позицию, возвращает установленую относительно начала
  126. dword File::SetPos(dword distanceToMove, MoveMethod moveMethod)
  127. {
  128. dword method = FILE_BEGIN;
  129. switch(moveMethod)
  130. {
  131. case from_current:
  132. method = FILE_CURRENT;
  133. break;
  134. case from_end:
  135. method = FILE_END;
  136. break;
  137. }
  138. dword newPos = ::SetFilePointer(handle, distanceToMove, null, method);
  139. if(newPos == INVALID_SET_FILE_POINTER)
  140. {
  141. return 0;
  142. }
  143. return newPos;
  144. }
  145. //Получить текущую позицию относительно начала
  146. dword File::GetPos() const
  147. {
  148. dword curPos = ::SetFilePointer(handle, 0, null, FILE_CURRENT);
  149. if(curPos == INVALID_SET_FILE_POINTER)
  150. {
  151. return 0;
  152. }
  153. return curPos;
  154. }
  155. //Получить размер файла
  156. dword File::Size() const
  157. {
  158. dword size = ::GetFileSize(handle, null);
  159. if(size == INVALID_FILE_SIZE)
  160. {
  161. return 0;
  162. }
  163. return size;
  164. }
  165. //Обрезать файл по текущей позиции
  166. bool File::Truncate()
  167. {
  168. bool res = ::SetEndOfFile(handle) != 0;
  169. return res;
  170. }
  171. #endif