您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

322 行
9.8KB

  1. /* FatLib Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the FatLib Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the FatLib Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef FatFileSystem_h
  21. #define FatFileSystem_h
  22. #include "FatVolume.h"
  23. #include "FatFile.h"
  24. #include "ArduinoStream.h"
  25. #include "ArduinoFiles.h"
  26. /**
  27. * \file
  28. * \brief FatFileSystem class
  29. */
  30. //------------------------------------------------------------------------------
  31. /**
  32. * \class FatFileSystem
  33. * \brief Integration class for the FatLib library.
  34. */
  35. class FatFileSystem : public FatVolume {
  36. public:
  37. /**
  38. * Initialize an FatFileSystem object.
  39. * \param[in] blockDev Device block driver.
  40. * \param[in] part partition to initialize.
  41. * \return The value true is returned for success and
  42. * the value false is returned for failure.
  43. */
  44. bool begin(BlockDriver* blockDev, uint8_t part = 0) {
  45. m_blockDev = blockDev;
  46. vwd()->close();
  47. return (part ? init(part) : init(1) || init(0))
  48. && vwd()->openRoot(this) && FatFile::setCwd(vwd());
  49. }
  50. #if ENABLE_ARDUINO_FEATURES
  51. /** List the directory contents of the volume working directory to Serial.
  52. *
  53. * \param[in] flags The inclusive OR of
  54. *
  55. * LS_DATE - %Print file modification date
  56. *
  57. * LS_SIZE - %Print file size.
  58. *
  59. * LS_R - Recursive list of subdirectories.
  60. */
  61. void ls(uint8_t flags = 0) {
  62. ls(&Serial, flags);
  63. }
  64. /** List the directory contents of a directory to Serial.
  65. *
  66. * \param[in] path directory to list.
  67. *
  68. * \param[in] flags The inclusive OR of
  69. *
  70. * LS_DATE - %Print file modification date
  71. *
  72. * LS_SIZE - %Print file size.
  73. *
  74. * LS_R - Recursive list of subdirectories.
  75. */
  76. void ls(const char* path, uint8_t flags = 0) {
  77. ls(&Serial, path, flags);
  78. }
  79. /** open a file
  80. *
  81. * \param[in] path location of file to be opened.
  82. * \param[in] mode open mode flags.
  83. * \return a File object.
  84. */
  85. File open(const char *path, uint8_t mode = FILE_READ) {
  86. File tmpFile;
  87. tmpFile.open(vwd(), path, mode);
  88. return tmpFile;
  89. }
  90. /** open a file
  91. *
  92. * \param[in] path location of file to be opened.
  93. * \param[in] mode open mode flags.
  94. * \return a File object.
  95. */
  96. File open(const String &path, uint8_t mode = FILE_READ) {
  97. return open(path.c_str(), mode );
  98. }
  99. #endif // ENABLE_ARDUINO_FEATURES
  100. /** Change a volume's working directory to root
  101. *
  102. * Changes the volume's working directory to the SD's root directory.
  103. * Optionally set the current working directory to the volume's
  104. * working directory.
  105. *
  106. * \param[in] set_cwd Set the current working directory to this volume's
  107. * working directory if true.
  108. *
  109. * \return The value true is returned for success and
  110. * the value false is returned for failure.
  111. */
  112. bool chdir(bool set_cwd = false) {
  113. vwd()->close();
  114. return vwd()->openRoot(this) && (set_cwd ? FatFile::setCwd(vwd()) : true);
  115. }
  116. /** Change a volume's working directory
  117. *
  118. * Changes the volume working directory to the \a path subdirectory.
  119. * Optionally set the current working directory to the volume's
  120. * working directory.
  121. *
  122. * Example: If the volume's working directory is "/DIR", chdir("SUB")
  123. * will change the volume's working directory from "/DIR" to "/DIR/SUB".
  124. *
  125. * If path is "/", the volume's working directory will be changed to the
  126. * root directory
  127. *
  128. * \param[in] path The name of the subdirectory.
  129. *
  130. * \param[in] set_cwd Set the current working directory to this volume's
  131. * working directory if true.
  132. *
  133. * \return The value true is returned for success and
  134. * the value false is returned for failure.
  135. */
  136. //----------------------------------------------------------------------------
  137. bool chdir(const char *path, bool set_cwd = false) {
  138. FatFile dir;
  139. if (path[0] == '/' && path[1] == '\0') {
  140. return chdir(set_cwd);
  141. }
  142. if (!dir.open(vwd(), path, O_READ)) {
  143. goto fail;
  144. }
  145. if (!dir.isDir()) {
  146. goto fail;
  147. }
  148. m_vwd = dir;
  149. if (set_cwd) {
  150. FatFile::setCwd(vwd());
  151. }
  152. return true;
  153. fail:
  154. return false;
  155. }
  156. //----------------------------------------------------------------------------
  157. /** Set the current working directory to a volume's working directory.
  158. *
  159. * This is useful with multiple SD cards.
  160. *
  161. * The current working directory is changed to this
  162. * volume's working directory.
  163. *
  164. * This is like the Windows/DOS \<drive letter>: command.
  165. */
  166. void chvol() {
  167. FatFile::setCwd(vwd());
  168. }
  169. //----------------------------------------------------------------------------
  170. /**
  171. * Test for the existence of a file.
  172. *
  173. * \param[in] path Path of the file to be tested for.
  174. *
  175. * \return true if the file exists else false.
  176. */
  177. bool exists(const char* path) {
  178. return vwd()->exists(path);
  179. }
  180. //----------------------------------------------------------------------------
  181. /** List the directory contents of the volume working directory.
  182. *
  183. * \param[in] pr Print stream for list.
  184. *
  185. * \param[in] flags The inclusive OR of
  186. *
  187. * LS_DATE - %Print file modification date
  188. *
  189. * LS_SIZE - %Print file size.
  190. *
  191. * LS_R - Recursive list of subdirectories.
  192. */
  193. void ls(print_t* pr, uint8_t flags = 0) {
  194. vwd()->ls(pr, flags);
  195. }
  196. //----------------------------------------------------------------------------
  197. /** List the directory contents of a directory.
  198. *
  199. * \param[in] pr Print stream for list.
  200. *
  201. * \param[in] path directory to list.
  202. *
  203. * \param[in] flags The inclusive OR of
  204. *
  205. * LS_DATE - %Print file modification date
  206. *
  207. * LS_SIZE - %Print file size.
  208. *
  209. * LS_R - Recursive list of subdirectories.
  210. */
  211. void ls(print_t* pr, const char* path, uint8_t flags) {
  212. FatFile dir;
  213. dir.open(vwd(), path, O_READ);
  214. dir.ls(pr, flags);
  215. }
  216. //----------------------------------------------------------------------------
  217. /** Make a subdirectory in the volume working directory.
  218. *
  219. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  220. *
  221. * \param[in] pFlag Create missing parent directories if true.
  222. *
  223. * \return The value true is returned for success and
  224. * the value false is returned for failure.
  225. */
  226. bool mkdir(const char* path, bool pFlag = true) {
  227. FatFile sub;
  228. return sub.mkdir(vwd(), path, pFlag);
  229. }
  230. //----------------------------------------------------------------------------
  231. /** Remove a file from the volume working directory.
  232. *
  233. * \param[in] path A path with a valid 8.3 DOS name for the file.
  234. *
  235. * \return The value true is returned for success and
  236. * the value false is returned for failure.
  237. */
  238. bool remove(const char* path) {
  239. return FatFile::remove(vwd(), path);
  240. }
  241. //----------------------------------------------------------------------------
  242. /** Rename a file or subdirectory.
  243. *
  244. * \param[in] oldPath Path name to the file or subdirectory to be renamed.
  245. *
  246. * \param[in] newPath New path name of the file or subdirectory.
  247. *
  248. * The \a newPath object must not exist before the rename call.
  249. *
  250. * The file to be renamed must not be open. The directory entry may be
  251. * moved and file system corruption could occur if the file is accessed by
  252. * a file object that was opened before the rename() call.
  253. *
  254. * \return The value true is returned for success and
  255. * the value false is returned for failure.
  256. */
  257. bool rename(const char *oldPath, const char *newPath) {
  258. FatFile file;
  259. if (!file.open(vwd(), oldPath, O_READ)) {
  260. return false;
  261. }
  262. return file.rename(vwd(), newPath);
  263. }
  264. //----------------------------------------------------------------------------
  265. /** Remove a subdirectory from the volume's working directory.
  266. *
  267. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  268. *
  269. * The subdirectory file will be removed only if it is empty.
  270. *
  271. * \return The value true is returned for success and
  272. * the value false is returned for failure.
  273. */
  274. bool rmdir(const char* path) {
  275. FatFile sub;
  276. if (!sub.open(vwd(), path, O_READ)) {
  277. return false;
  278. }
  279. return sub.rmdir();
  280. }
  281. //----------------------------------------------------------------------------
  282. /** Truncate a file to a specified length. The current file position
  283. * will be maintained if it is less than or equal to \a length otherwise
  284. * it will be set to end of file.
  285. *
  286. * \param[in] path A path with a valid 8.3 DOS name for the file.
  287. * \param[in] length The desired length for the file.
  288. *
  289. * \return The value true is returned for success and
  290. * the value false is returned for failure.
  291. */
  292. bool truncate(const char* path, uint32_t length) {
  293. FatFile file;
  294. if (!file.open(vwd(), path, O_WRITE)) {
  295. return false;
  296. }
  297. return file.truncate(length);
  298. }
  299. /** \return a pointer to the FatVolume object. */
  300. FatVolume* vol() {
  301. return this;
  302. }
  303. /** \return a pointer to the volume working directory. */
  304. FatFile* vwd() {
  305. return &m_vwd;
  306. }
  307. /** Wipe all data from the volume. You must reinitialize the volume before
  308. * accessing it again.
  309. * \param[in] pr print stream for status dots.
  310. * \return true for success else false.
  311. */
  312. bool wipe(print_t* pr = 0) {
  313. vwd()->close();
  314. return FatVolume::wipe(pr);
  315. }
  316. private:
  317. FatFile m_vwd;
  318. };
  319. #endif // FatFileSystem_h