file.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include "file.h"
  2. #include <util/memory/blob.h>
  3. #include <util/generic/yexception.h>
  4. TUnbufferedFileInput::TUnbufferedFileInput(const char* path)
  5. : TUnbufferedFileInput(TFile(path, OPEN_MODE))
  6. {
  7. }
  8. TUnbufferedFileInput::TUnbufferedFileInput(const TString& path)
  9. : TUnbufferedFileInput(TFile(path, OPEN_MODE))
  10. {
  11. }
  12. TUnbufferedFileInput::TUnbufferedFileInput(const std::filesystem::path& path)
  13. : TUnbufferedFileInput(TFile(path, OPEN_MODE))
  14. {
  15. }
  16. TUnbufferedFileInput::TUnbufferedFileInput(const TFile& file)
  17. : File_(file)
  18. {
  19. if (!File_.IsOpen()) {
  20. ythrow TIoException() << "file (" << file.GetName() << ") not open";
  21. }
  22. }
  23. size_t TUnbufferedFileInput::DoRead(void* buf, size_t len) {
  24. return File_.ReadOrFail(buf, len);
  25. }
  26. size_t TUnbufferedFileInput::DoSkip(size_t len) {
  27. if (len < 384) {
  28. /* Base implementation calls DoRead, which results in one system call
  29. * instead of three as in fair skip implementation. For small sizes
  30. * actually doing one read is cheaper. Experiments show that the
  31. * border that separates two implementations performance-wise lies
  32. * in the range of 384-512 bytes (assuming that the file is in OS cache). */
  33. return IInputStream::DoSkip(len);
  34. }
  35. /* TFile::Seek can seek beyond the end of file, so we need to do
  36. * size check here. */
  37. i64 size = File_.GetLength();
  38. i64 oldPos = File_.GetPosition();
  39. i64 newPos = File_.Seek(Min<i64>(size, oldPos + len), sSet);
  40. return newPos - oldPos;
  41. }
  42. TUnbufferedFileOutput::TUnbufferedFileOutput(const char* path)
  43. : TUnbufferedFileOutput(TFile(path, OPEN_MODE))
  44. {
  45. }
  46. TUnbufferedFileOutput::TUnbufferedFileOutput(const TString& path)
  47. : TUnbufferedFileOutput(TFile(path, OPEN_MODE))
  48. {
  49. }
  50. TUnbufferedFileOutput::TUnbufferedFileOutput(const std::filesystem::path& path)
  51. : TUnbufferedFileOutput(TFile(path, OPEN_MODE))
  52. {
  53. }
  54. TUnbufferedFileOutput::TUnbufferedFileOutput(const TFile& file)
  55. : File_(file)
  56. {
  57. if (!File_.IsOpen()) {
  58. ythrow TIoException() << "closed file(" << file.GetName() << ") passed";
  59. }
  60. }
  61. TUnbufferedFileOutput::~TUnbufferedFileOutput() = default;
  62. void TUnbufferedFileOutput::DoWrite(const void* buf, size_t len) {
  63. File_.Write(buf, len);
  64. }
  65. void TUnbufferedFileOutput::DoFlush() {
  66. if (File_.IsOpen()) {
  67. File_.Flush();
  68. }
  69. }
  70. class TMappedFileInput::TImpl: public TBlob {
  71. public:
  72. inline TImpl(const TFile& file)
  73. : TBlob(TBlob::FromFile(file))
  74. {
  75. }
  76. inline ~TImpl() = default;
  77. };
  78. TMappedFileInput::TMappedFileInput(const TFile& file)
  79. : TMemoryInput(nullptr, 0)
  80. , Impl_(new TImpl(file))
  81. {
  82. Reset(Impl_->Data(), Impl_->Size());
  83. }
  84. TMappedFileInput::TMappedFileInput(const TString& path)
  85. : TMemoryInput(nullptr, 0)
  86. , Impl_(new TImpl(TFile(path, OpenExisting | RdOnly)))
  87. {
  88. Reset(Impl_->Data(), Impl_->Size());
  89. }
  90. TMappedFileInput::~TMappedFileInput() = default;