file.cpp 2.6 KB

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