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 17 #ifndef MINDSPORE_CCSRC_UTILS_SYSTEM_FILE_SYSTEM_H_ 18 #define MINDSPORE_CCSRC_UTILS_SYSTEM_FILE_SYSTEM_H_ 19 20 #include <errno.h> 21 #include <sys/param.h> 22 #include <cstdint> 23 #include <cstdlib> 24 #include <cstdio> 25 #include <functional> 26 #include <string> 27 #include <memory> 28 #include <vector> 29 #include "utils/system/base.h" 30 #include "utils/log_adapter.h" 31 #include "debug/common.h" 32 33 namespace mindspore { 34 namespace system { 35 36 class WriteFile; 37 class PosixWriteFile; 38 using WriteFilePtr = std::shared_ptr<WriteFile>; 39 using PosixWriteFilePtr = std::shared_ptr<PosixWriteFile>; 40 41 // File system of create or delete directory 42 class FileSystem { 43 public: 44 FileSystem() = default; 45 46 virtual ~FileSystem() = default; 47 48 // Create a new read/write file 49 virtual WriteFilePtr CreateWriteFile(const string &file_name) = 0; 50 51 // Check the file is exist? 52 virtual bool FileExist(const string &file_name) = 0; 53 54 // Delete the file 55 virtual bool DeleteFile(const string &file_name) = 0; 56 57 // Create a directory 58 virtual bool CreateDir(const string &dir_name) = 0; 59 60 // Delete the specified directory 61 virtual bool DeleteDir(const string &dir_name) = 0; 62 }; 63 64 // A file that can be read and write 65 class WriteFile { 66 public: WriteFile(const string & file_name)67 explicit WriteFile(const string &file_name) : file_name_(file_name) {} 68 69 virtual ~WriteFile() = default; 70 71 // Open the file 72 virtual bool Open() = 0; 73 74 // append the content to file Write(const std::string & data)75 virtual bool Write(const std::string &data) { 76 MS_LOG(WARNING) << "Attention: Maybe not call the function."; 77 return true; 78 } 79 80 // name: return the file name get_file_name()81 string get_file_name() { return file_name_; } 82 83 // flush: flush local buffer data to filesystem. 84 virtual bool Flush() = 0; 85 86 // sync: sync the content to disk 87 virtual bool Sync() = 0; 88 89 // close the file 90 virtual bool Close() = 0; 91 92 protected: 93 string file_name_; 94 }; 95 96 #if defined(SYSTEM_ENV_POSIX) 97 // File system of create or delete directory for posix system 98 class PosixFileSystem : public FileSystem { 99 public: 100 PosixFileSystem() = default; 101 102 ~PosixFileSystem() override = default; 103 104 // create a new write file 105 WriteFilePtr CreateWriteFile(const string &file_name) override; 106 107 // check the file is exist? 108 bool FileExist(const string &file_name) override; 109 110 // delete the file 111 bool DeleteFile(const string &file_name) override; 112 113 // Create a Directory 114 bool CreateDir(const string &dir_name) override; 115 116 // Delete the specified directory. 117 bool DeleteDir(const string &dir_name) override; 118 }; 119 120 // A file that can be read and write for posix 121 class PosixWriteFile : public WriteFile { 122 public: PosixWriteFile(const string & file_name)123 explicit PosixWriteFile(const string &file_name) : WriteFile(file_name), file_(nullptr) {} 124 PosixWriteFile(const PosixWriteFile &); 125 PosixWriteFile &operator=(const PosixWriteFile &); 126 ~PosixWriteFile()127 ~PosixWriteFile() override { 128 try { 129 if (file_ != nullptr) { 130 (void)fclose(file_); 131 file_ = nullptr; 132 } 133 } catch (const std::exception &e) { 134 MS_LOG(ERROR) << "Exception when closing file."; 135 } catch (...) { 136 MS_LOG(ERROR) << "Non standard exception when closing file."; 137 } 138 } 139 Open()140 bool Open() override { 141 if (file_ != nullptr) { 142 MS_LOG(WARNING) << "The File(" << file_name_ << ") already open."; 143 return true; 144 } 145 // check the path 146 if (nullptr == file_name_.c_str()) { 147 MS_LOG(EXCEPTION) << "The file path is null."; 148 } 149 char path[PATH_MAX] = {0x00}; 150 if (file_name_.size() >= PATH_MAX || nullptr == realpath(file_name_.c_str(), path)) { 151 MS_LOG(EXCEPTION) << "Convert to real path fail, file name is " << file_name_ << "."; 152 } 153 154 // open the file 155 file_ = fopen(path, "w+"); 156 if (file_ == nullptr) { 157 MS_LOG(ERROR) << "File(" << path << ") IO ERROR. " << ErrnoToString(errno); 158 return false; 159 } 160 return true; 161 } 162 Write(const std::string & data)163 bool Write(const std::string &data) override { 164 MS_LOG(DEBUG) << "Write data(" << data.size() << ") to file(" << this->file_name_ << ")."; 165 size_t r = fwrite(data.data(), 1, data.size(), file_); 166 if (r != data.size()) { 167 MS_LOG(ERROR) << "File(" << file_name_ << ") IO ERROR. " << ErrnoToString(errno); 168 return false; 169 } 170 return true; 171 } 172 Close()173 bool Close() override { 174 if (file_ == nullptr) { 175 MS_LOG(INFO) << "File(" << file_name_ << ") already close."; 176 return true; 177 } 178 bool result = true; 179 if (fclose(file_) != 0) { 180 MS_LOG(ERROR) << "File(" << file_name_ << ") IO ERROR. " << ErrnoToString(errno); 181 result = false; 182 } 183 file_ = nullptr; 184 return result; 185 } 186 Flush()187 bool Flush() override { 188 if (fflush(file_) != 0) { 189 MS_LOG(ERROR) << "File(" << file_name_ << ") IO ERROR. " << ErrnoToString(errno); 190 return false; 191 } 192 return true; 193 } 194 Sync()195 bool Sync() override { return Flush(); } 196 197 private: 198 FILE *file_; 199 }; 200 #endif 201 202 #if defined(SYSTEM_ENV_WINDOWS) 203 // File system of create or delete directory for windows system 204 class WinFileSystem : public FileSystem { 205 public: 206 WinFileSystem() = default; 207 208 ~WinFileSystem() override = default; 209 210 // create a new write file 211 WriteFilePtr CreateWriteFile(const string &file_name) override; 212 213 // check the file is exist? 214 bool FileExist(const string &file_name) override; 215 216 // delete the file 217 bool DeleteFile(const string &file_name) override; 218 219 // Create a Directory 220 bool CreateDir(const string &dir_name) override; 221 222 // Delete the specified directory. 223 bool DeleteDir(const string &dir_name) override; 224 }; 225 226 // A file that can be read and write for windows 227 class WinWriteFile : public WriteFile { 228 public: WinWriteFile(const string & file_name)229 explicit WinWriteFile(const string &file_name) : WriteFile(file_name), file_(nullptr) {} 230 231 ~WinWriteFile() override; 232 233 bool Open() override; 234 235 bool Write(const std::string &data) override; 236 237 bool Close() override; 238 239 bool Flush() override; 240 241 bool Sync() override; 242 243 private: 244 FILE *file_; 245 }; 246 #endif 247 } // namespace system 248 } // namespace mindspore 249 250 #endif // MINDSPORE_CCSRC_UTILS_SYSTEM_FILE_SYSTEM_H_ 251