file.h 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #ifndef FILE_H
  2. #define FILE_H
  3. #if __has_include(<filesystem>)
  4. #include <filesystem>
  5. namespace fs = std::filesystem;
  6. #elif __has_include(<experimental/filesystem>)
  7. #include <experimental/filesystem>
  8. namespace fs = std::experimental::filesystem;
  9. #endif
  10. #include <fstream>
  11. #include <shared_mutex>
  12. #include "byte_array.h"
  13. namespace binom {
  14. class FileIO {
  15. public:
  16. typedef std::basic_ifstream<char> Reader;
  17. typedef std::basic_fstream<char> Writer;
  18. private:
  19. fs::path file_path;
  20. std::shared_mutex mtx;
  21. inline Reader getReader() {return Reader(file_path.string(), std::ios::binary);}
  22. inline Writer getWriter() {return Writer(file_path.string(), std::ios::binary | std::ios::out | std::ios::in);}
  23. public:
  24. static inline bool isExist(std::string_view file_path) {return fs::exists(file_path);}
  25. static inline bool isRegularFile(std::string_view file_path) {return fs::is_regular_file(file_path);}
  26. FileIO(std::string_view str) : file_path(str) {if(!isExist())std::ofstream(file_path.string(), std::ios::binary | std::ios::out);}
  27. FileIO(const FileIO& other) : file_path(other.file_path) {}
  28. FileIO(FileIO&& other) : file_path(std::move(other.file_path)) {}
  29. inline bool isExist() const {return fs::exists(file_path);}
  30. inline bool isEmpty() const {return fs::is_empty(file_path);}
  31. inline ui64 getSize() const {return fs::file_size(file_path);}
  32. inline fs::path getPath() const {return file_path;}
  33. inline void resize(ui64 new_size) {fs::resize_file(file_path, new_size);}
  34. inline ui64 addSize(ui64 add_size) {
  35. ui64 pos = getSize();
  36. fs::resize_file(file_path, pos + add_size);
  37. return pos;
  38. }
  39. inline void subSize(ui64 sub_size) {return fs::resize_file(file_path, getSize() - sub_size);}
  40. bool readBuffer(void* buffer, ui64 pos, ui64 size) {
  41. Reader reader = getReader();
  42. if(!reader.is_open()) return false;
  43. mtx.lock_shared();
  44. reader.seekg(pos, std::ios::beg);
  45. reader.read(static_cast<char*>(buffer), size);
  46. mtx.unlock_shared();
  47. return true;
  48. }
  49. template<typename T>
  50. T read(ui64 from) {
  51. T to;
  52. readBuffer(&to, from, sizeof(to));
  53. return to;
  54. }
  55. template<typename T>
  56. bool read(T& to, ui64 from) { return readBuffer(&to, from, sizeof(to)); }
  57. bool read(ByteArray& to, ui64 from) { return readBuffer(to.begin(), from, to.length()); }
  58. ByteArray read(ui64 from, ui64 size) {
  59. ByteArray data(size);
  60. readBuffer(data.begin(), from, size);
  61. return data;
  62. }
  63. bool writeBuffer(void* buffer, ui64 pos, ui64 size) {
  64. Writer writer = getWriter();
  65. if(!writer.is_open()) return false;
  66. mtx.lock();
  67. writer.seekp(pos, std::ios::beg);
  68. writer.write(static_cast<char*>(buffer), size);
  69. writer.flush();
  70. mtx.unlock();
  71. return true;
  72. }
  73. template<typename T>
  74. bool write(ui64 to, T& from) { return writeBuffer(&from, to, sizeof(from)); }
  75. bool write(ui64 to, const ByteArray from) { return writeBuffer(from.begin(), to, from.length()); }
  76. };
  77. }
  78. #endif // FILE_H