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

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #include "FileStream.h"
  3. #include <assert.h>
  4. #include <string.h>
  5. #include <sstream>
  6. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  7. # include <io.h>
  8. // # if defined(_POSIX_)
  9. // # endif
  10. #else
  11. # include <unistd.h>
  12. #endif
  13. # include <sys/stat.h>
  14. # include <sys/types.h>
  15. # include <fcntl.h>
  16. # include <errno.h>
  17. #   include "byte_io_impl.h"
  18. namespace febird {
  19. FileStream::FileStream(const char* fpath, const char* mode)
  20. {
  21. m_fp = 0;
  22.     open(fpath, mode);
  23. }
  24. FileStream::FileStream(int fd, const char* mode)
  25. {
  26. dopen(fd, mode);
  27. }
  28. void FileStream::ThrowOpenFileException(const char* fpath, const char* mode)
  29. {
  30. std::ostringstream oss;
  31. oss << "mode=" << mode;
  32. throw OpenFileException(fpath, oss.str().c_str());
  33. }
  34. // only can call on unopened FileStream
  35. void FileStream::open(const char* fpath, const char* mode)
  36. {
  37. assert(0 == m_fp);
  38. m_fp = fopen(fpath, mode);
  39. if (0 == m_fp)
  40. ThrowOpenFileException(fpath, mode);
  41. }
  42. bool FileStream::xopen(const char* fpath, const char* mode) throw()
  43. {
  44. assert(0 == m_fp);
  45. m_fp = fopen(fpath, mode);
  46. return 0 != m_fp;
  47. }
  48. void FileStream::dopen(int fd, const char* mode) throw()
  49. {
  50. assert(0 == m_fp);
  51. #ifdef _MSC_VER
  52. m_fp = ::_fdopen(fd, mode);
  53. #else
  54. m_fp = ::fdopen(fd, mode);
  55. #endif
  56. if (0 == m_fp)
  57. {
  58. char szbuf[64];
  59. sprintf(szbuf, "fd=%d");
  60. ThrowOpenFileException(szbuf, mode);
  61. }
  62. }
  63. void FileStream::attach(::FILE* fp) throw()
  64. {
  65. assert(0 == m_fp);
  66. this->m_fp = fp;
  67. }
  68. FILE* FileStream::detach() throw()
  69. {
  70. assert(m_fp);
  71. FILE* temp = m_fp;
  72. m_fp = 0;
  73. return m_fp;
  74. }
  75. void FileStream::close() throw()
  76. {
  77. assert(m_fp);
  78. fclose(m_fp);
  79. m_fp = 0;
  80. }
  81. stream_position_t FileStream::tell()
  82. {
  83. assert(m_fp);
  84. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  85. fpos_t pos;
  86. if (fgetpos(m_fp, &pos) != 0)
  87. throw IOException(BOOST_CURRENT_FUNCTION);
  88. return stream_position_t(pos);
  89. #else
  90. return (size_t)::ftell(m_fp);
  91. #endif
  92. }
  93. void FileStream::seek(stream_offset_t offset, int origin)
  94. {
  95. assert(m_fp);
  96. if (::fseek(m_fp, offset, origin) != 0)
  97. throw IOException(BOOST_CURRENT_FUNCTION);
  98. }
  99. void FileStream::seek(stream_position_t pos)
  100. {
  101. assert(m_fp);
  102. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  103. fpos_t x_fpos = pos;
  104. if (::fsetpos(m_fp, &x_fpos) != 0)
  105. throw IOException(BOOST_CURRENT_FUNCTION);
  106. #else
  107. seek(long(pos), 0);
  108. #endif
  109. }
  110. void FileStream::flush()
  111. {
  112. assert(m_fp);
  113. if (::fflush(m_fp) == EOF)
  114. throw DelayedWriteFailException(BOOST_CURRENT_FUNCTION);
  115. }
  116. stream_position_t FileStream::size() const throw()
  117. {
  118. assert(m_fp);
  119. #if (defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)) && !defined(_POSIX_)
  120. int fno = ::_fileno(m_fp);
  121. return ::_filelength(fno);
  122. #else
  123. struct stat x = { 0 };
  124. ::fstat(fileno(m_fp), &x);
  125. return x.st_size;
  126. #endif
  127. }
  128. size_t FileStream::read(void* buf, size_t size) throw()
  129. {
  130. assert(m_fp);
  131. return ::fread(buf, 1, size, m_fp);
  132. }
  133. size_t FileStream::write(const void* buf, size_t size) throw()
  134. {
  135. assert(m_fp);
  136. return ::fwrite(buf, 1, size, m_fp);
  137. }
  138. FEBIRD_GEN_ensureRead (FileStream::)
  139. FEBIRD_GEN_ensureWrite(FileStream::)
  140. void FileStream::disbuf() throw()
  141. {
  142. assert(m_fp);
  143. setvbuf(m_fp, NULL, _IONBF, 0);
  144. }
  145. //////////////////////////////////////////////////////////////////////
  146. bool FileStream::copyFile(const char* srcPath, const char* dstPath)
  147. {
  148. FileStream fsrc(srcPath, "rb");
  149. FileStream fdst(dstPath, "wb+");
  150. if (fsrc && fdst)
  151. {
  152. setvbuf(fsrc.fp(), NULL, _IONBF, 0);
  153. setvbuf(fdst.fp(), NULL, _IONBF, 0);
  154. size_t nbuf = 64 * 1024;
  155. char*  pbuf = (char*)malloc(nbuf);
  156. try {
  157. while (!fsrc.eof())
  158. {
  159. size_t nRead  = fsrc.read(pbuf, nbuf);
  160. size_t nWrite = fdst.write(pbuf, nRead);
  161. if (nWrite != nRead) {
  162. throw OutOfSpaceException(BOOST_CURRENT_FUNCTION);
  163. }
  164. }
  165. free(pbuf);
  166. } catch (const std::exception& ) {
  167. free(pbuf);
  168. throw;
  169. }
  170. return true;
  171. }
  172. return false;
  173. }
  174. } // namespace febird