You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

path.cc 5.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /**
  2. * Copyright 2019 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "dataset/util/path.h"
  17. #include <sys/stat.h>
  18. #include <new>
  19. #include <sstream>
  20. #include <utility>
  21. #include "common/utils.h"
  22. #include "dataset/util/de_error.h"
  23. #include "utils/log_adapter.h"
  24. namespace mindspore {
  25. namespace dataset {
  26. #ifdef _WIN32
  27. char Path::separator_ = '\\';
  28. #else
  29. char Path::separator_ = '/';
  30. #endif
  31. Path::Path(const std::string &s) : path_(s) {}
  32. Path::Path(const char *p) : path_(p) {}
  33. Path::Path(const Path &p) : path_(p.path_) {}
  34. Path &Path::operator=(const Path &p) {
  35. if (&p != this) {
  36. this->path_ = p.path_;
  37. }
  38. return *this;
  39. }
  40. Path &Path::operator=(Path &&p) noexcept {
  41. if (&p != this) {
  42. this->path_ = std::move(p.path_);
  43. }
  44. return *this;
  45. }
  46. Path::Path(Path &&p) noexcept { this->path_ = std::move(p.path_); }
  47. Path Path::operator+(const Path &p) {
  48. std::string q = path_ + p.toString();
  49. return Path(q);
  50. }
  51. Path Path::operator+(const std::string &p) {
  52. std::string q = path_ + p;
  53. return Path(q);
  54. }
  55. Path Path::operator+(const char *p) {
  56. std::string q = path_ + p;
  57. return Path(q);
  58. }
  59. Path &Path::operator+=(const Path &rhs) {
  60. path_ += rhs.toString();
  61. return *this;
  62. }
  63. Path &Path::operator+=(const std::string &p) {
  64. path_ += p;
  65. return *this;
  66. }
  67. Path &Path::operator+=(const char *p) {
  68. path_ += p;
  69. return *this;
  70. }
  71. Path Path::operator/(const Path &p) {
  72. std::string q = path_ + separator_ + p.toString();
  73. return Path(q);
  74. }
  75. Path Path::operator/(const std::string &p) {
  76. std::string q = path_ + separator_ + p;
  77. return Path(q);
  78. }
  79. Path Path::operator/(const char *p) {
  80. std::string q = path_ + separator_ + p;
  81. return Path(q);
  82. }
  83. std::string Path::Extension() const {
  84. std::size_t found = path_.find_last_of('.');
  85. if (found != std::string::npos) {
  86. return path_.substr(found);
  87. } else {
  88. return std::string("");
  89. }
  90. }
  91. bool Path::Exists() {
  92. struct stat sb;
  93. int rc = stat(common::SafeCStr(path_), &sb);
  94. if (rc == -1 && errno != ENOENT) {
  95. MS_LOG(WARNING) << "Unable to query the status of " << path_ << ". Errno = " << errno << ".";
  96. }
  97. return (rc == 0);
  98. }
  99. bool Path::IsDirectory() {
  100. struct stat sb;
  101. int rc = stat(common::SafeCStr(path_), &sb);
  102. if (rc == 0) {
  103. return S_ISDIR(sb.st_mode);
  104. } else {
  105. return false;
  106. }
  107. }
  108. Status Path::CreateDirectory() {
  109. if (!Exists()) {
  110. #if defined(_WIN32) || defined(_WIN64)
  111. int rc = mkdir(common::SafeCStr(path_));
  112. #else
  113. int rc = mkdir(common::SafeCStr(path_), 0700);
  114. #endif
  115. if (rc) {
  116. std::ostringstream oss;
  117. oss << "Unable to create directory " << path_ << ". Errno = " << errno;
  118. RETURN_STATUS_UNEXPECTED(oss.str());
  119. }
  120. return Status::OK();
  121. } else {
  122. if (IsDirectory()) {
  123. return Status::OK();
  124. } else {
  125. std::ostringstream oss;
  126. oss << "Unable to create directory " << path_ << ". It exists but is not a directory";
  127. RETURN_STATUS_UNEXPECTED(oss.str());
  128. }
  129. }
  130. }
  131. std::string Path::ParentPath() {
  132. std::string r("");
  133. std::size_t found = path_.find_last_of(separator_);
  134. if (found != std::string::npos) {
  135. if (found == 0) {
  136. r += separator_;
  137. } else {
  138. r = std::string(path_.substr(0, found));
  139. }
  140. }
  141. return r;
  142. }
  143. Status Path::CreateDirectories() {
  144. if (IsDirectory()) {
  145. MS_LOG(DEBUG) << "Directory " << toString() << " already exists.";
  146. return Status::OK();
  147. } else {
  148. MS_LOG(DEBUG) << "Creating directory " << toString() << ".";
  149. std::string parent = ParentPath();
  150. if (!parent.empty()) {
  151. if (Path(parent).CreateDirectories()) {
  152. return CreateDirectory();
  153. }
  154. } else {
  155. return CreateDirectory();
  156. }
  157. }
  158. return Status::OK();
  159. }
  160. std::shared_ptr<Path::DirIterator> Path::DirIterator::OpenDirectory(Path *f) {
  161. auto it = new (std::nothrow) DirIterator(f);
  162. if (it == nullptr) {
  163. return nullptr;
  164. }
  165. if (it->dp_) {
  166. return std::shared_ptr<DirIterator>(it);
  167. } else {
  168. delete it;
  169. return nullptr;
  170. }
  171. }
  172. Path::DirIterator::~DirIterator() {
  173. if (dp_) {
  174. (void)closedir(dp_);
  175. }
  176. dp_ = nullptr;
  177. dir_ = nullptr;
  178. entry_ = nullptr;
  179. }
  180. Path::DirIterator::DirIterator(Path *f) : dir_(f), dp_(nullptr), entry_(nullptr) {
  181. MS_LOG(DEBUG) << "Open directory " << f->toString() << ".";
  182. dp_ = opendir(common::SafeCStr(f->toString()));
  183. }
  184. bool Path::DirIterator::hasNext() {
  185. do {
  186. entry_ = readdir(dp_);
  187. if (entry_) {
  188. if (strcmp(entry_->d_name, ".") == 0 || strcmp(entry_->d_name, "..") == 0) {
  189. continue;
  190. }
  191. }
  192. break;
  193. } while (true);
  194. return (entry_ != nullptr);
  195. }
  196. Path Path::DirIterator::next() { return (*(this->dir_) / Path(entry_->d_name)); }
  197. } // namespace dataset
  198. } // namespace mindspore