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

248 行
8.5KB

  1. /* Arduino SdFat Library
  2. * Copyright (C) 2012 by William Greiman
  3. *
  4. * This file is part of the Arduino SdFat 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 Arduino SdFat Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #include <SdFat.h>
  21. //------------------------------------------------------------------------------
  22. #if USE_SERIAL_FOR_STD_OUT || !defined(UDR0)
  23. Print* SdFat::m_stdOut = &Serial;
  24. #else // USE_SERIAL_FOR_STD_OUT
  25. #include <MinimumSerial.h>
  26. Print* SdFat::m_stdOut = &MiniSerial;
  27. #endif // USE_SERIAL_FOR_STD_OUT
  28. //------------------------------------------------------------------------------
  29. /**
  30. * Initialize an SdFat object.
  31. *
  32. * Initializes the SD card, SD volume, and root directory.
  33. *
  34. * \param[in] chipSelectPin SD chip select pin. See Sd2Card::init().
  35. * \param[in] sckDivisor value for SPI SCK divisor. See Sd2Card::init().
  36. *
  37. * \return The value one, true, is returned for success and
  38. * the value zero, false, is returned for failure.
  39. */
  40. bool SdFat::begin(uint8_t chipSelectPin, uint8_t sckDivisor) {
  41. return m_card.begin(chipSelectPin, sckDivisor)
  42. && m_vol.init(&m_card) && chdir(1);
  43. }
  44. //------------------------------------------------------------------------------
  45. /** Change a volume's working directory to root
  46. *
  47. * Changes the volume's working directory to the SD's root directory.
  48. * Optionally set the current working directory to the volume's
  49. * working directory.
  50. *
  51. * \param[in] set_cwd Set the current working directory to this volume's
  52. * working directory if true.
  53. *
  54. * \return The value one, true, is returned for success and
  55. * the value zero, false, is returned for failure.
  56. */
  57. bool SdFat::chdir(bool set_cwd) {
  58. if (set_cwd) SdBaseFile::setCwd(&m_vwd);
  59. if (m_vwd.isOpen()) m_vwd.close();
  60. return m_vwd.openRoot(&m_vol);
  61. }
  62. //------------------------------------------------------------------------------
  63. /** Change a volume's working directory
  64. *
  65. * Changes the volume working directory to the \a path subdirectory.
  66. * Optionally set the current working directory to the volume's
  67. * working directory.
  68. *
  69. * Example: If the volume's working directory is "/DIR", chdir("SUB")
  70. * will change the volume's working directory from "/DIR" to "/DIR/SUB".
  71. *
  72. * If path is "/", the volume's working directory will be changed to the
  73. * root directory
  74. *
  75. * \param[in] path The name of the subdirectory.
  76. *
  77. * \param[in] set_cwd Set the current working directory to this volume's
  78. * working directory if true.
  79. *
  80. * \return The value one, true, is returned for success and
  81. * the value zero, false, is returned for failure.
  82. */
  83. bool SdFat::chdir(const char *path, bool set_cwd) {
  84. SdBaseFile dir;
  85. dir.open(&m_vwd, path, O_READ);
  86. // Check for correctly open directory.
  87. if (!dir.isDir()) goto fail;
  88. m_vwd = dir;
  89. if (set_cwd) SdBaseFile::setCwd(&m_vwd);
  90. return true;
  91. fail:
  92. return false;
  93. }
  94. //------------------------------------------------------------------------------
  95. /** Set the current working directory to a volume's working directory.
  96. *
  97. * This is useful with multiple SD cards.
  98. *
  99. * The current working directory is changed to this volume's working directory.
  100. *
  101. * This is like the Windows/DOS \<drive letter>: command.
  102. */
  103. void SdFat::chvol() {
  104. SdBaseFile::setCwd(&m_vwd);
  105. }
  106. //------------------------------------------------------------------------------
  107. /**
  108. * Test for the existence of a file.
  109. *
  110. * \param[in] name Name of the file to be tested for.
  111. *
  112. * \return true if the file exists else false.
  113. */
  114. bool SdFat::exists(const char* name) {
  115. return m_vwd.exists(name);
  116. }
  117. //------------------------------------------------------------------------------
  118. /** List the directory contents of the volume working directory to stdOut.
  119. *
  120. * \param[in] flags The inclusive OR of
  121. *
  122. * LS_DATE - %Print file modification date
  123. *
  124. * LS_SIZE - %Print file size.
  125. *
  126. * LS_R - Recursive list of subdirectories.
  127. */
  128. void SdFat::ls(uint8_t flags) {
  129. m_vwd.ls(m_stdOut, flags);
  130. }
  131. //------------------------------------------------------------------------------
  132. /** List the directory contents of the volume working directory to stdOut.
  133. *
  134. * \param[in] path directory to list.
  135. *
  136. * \param[in] flags The inclusive OR of
  137. *
  138. * LS_DATE - %Print file modification date
  139. *
  140. * LS_SIZE - %Print file size.
  141. *
  142. * LS_R - Recursive list of subdirectories.
  143. */
  144. void SdFat::ls(const char* path, uint8_t flags) {
  145. ls(m_stdOut, path, flags);
  146. }
  147. //------------------------------------------------------------------------------
  148. /** List the directory contents of the volume working directory.
  149. *
  150. * \param[in] pr Print stream for list.
  151. *
  152. * \param[in] flags The inclusive OR of
  153. *
  154. * LS_DATE - %Print file modification date
  155. *
  156. * LS_SIZE - %Print file size.
  157. *
  158. * LS_R - Recursive list of subdirectories.
  159. */
  160. void SdFat::ls(Print* pr, uint8_t flags) {
  161. m_vwd.ls(pr, flags);
  162. }
  163. //------------------------------------------------------------------------------
  164. void SdFat::ls(Print* pr, const char* path, uint8_t flags) {
  165. SdBaseFile dir(path, O_READ);
  166. dir.ls(pr, flags);
  167. }
  168. //------------------------------------------------------------------------------
  169. /** Make a subdirectory in the volume working directory.
  170. *
  171. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  172. *
  173. * \param[in] pFlag Create missing parent directories if true.
  174. *
  175. * \return The value one, true, is returned for success and
  176. * the value zero, false, is returned for failure.
  177. */
  178. bool SdFat::mkdir(const char* path, bool pFlag) {
  179. SdBaseFile sub;
  180. return sub.mkdir(&m_vwd, path, pFlag);
  181. }
  182. //------------------------------------------------------------------------------
  183. /** Remove a file from the volume working directory.
  184. *
  185. * \param[in] path A path with a valid 8.3 DOS name for the file.
  186. *
  187. * \return The value one, true, is returned for success and
  188. * the value zero, false, is returned for failure.
  189. */
  190. bool SdFat::remove(const char* path) {
  191. return SdBaseFile::remove(&m_vwd, path);
  192. }
  193. //------------------------------------------------------------------------------
  194. /** Rename a file or subdirectory.
  195. *
  196. * \param[in] oldPath Path name to the file or subdirectory to be renamed.
  197. *
  198. * \param[in] newPath New path name of the file or subdirectory.
  199. *
  200. * The \a newPath object must not exist before the rename call.
  201. *
  202. * The file to be renamed must not be open. The directory entry may be
  203. * moved and file system corruption could occur if the file is accessed by
  204. * a file object that was opened before the rename() call.
  205. *
  206. * \return The value one, true, is returned for success and
  207. * the value zero, false, is returned for failure.
  208. */
  209. bool SdFat::rename(const char *oldPath, const char *newPath) {
  210. SdBaseFile file;
  211. if (!file.open(oldPath, O_READ)) return false;
  212. return file.rename(&m_vwd, newPath);
  213. }
  214. //------------------------------------------------------------------------------
  215. /** Remove a subdirectory from the volume's working directory.
  216. *
  217. * \param[in] path A path with a valid 8.3 DOS name for the subdirectory.
  218. *
  219. * The subdirectory file will be removed only if it is empty.
  220. *
  221. * \return The value one, true, is returned for success and
  222. * the value zero, false, is returned for failure.
  223. */
  224. bool SdFat::rmdir(const char* path) {
  225. SdBaseFile sub;
  226. if (!sub.open(path, O_READ)) return false;
  227. return sub.rmdir();
  228. }
  229. //------------------------------------------------------------------------------
  230. /** Truncate a file to a specified length. The current file position
  231. * will be maintained if it is less than or equal to \a length otherwise
  232. * it will be set to end of file.
  233. *
  234. * \param[in] path A path with a valid 8.3 DOS name for the file.
  235. * \param[in] length The desired length for the file.
  236. *
  237. * \return The value one, true, is returned for success and
  238. * the value zero, false, is returned for failure.
  239. * Reasons for failure include file is read only, file is a directory,
  240. * \a length is greater than the current file size or an I/O error occurs.
  241. */
  242. bool SdFat::truncate(const char* path, uint32_t length) {
  243. SdBaseFile file;
  244. if (!file.open(path, O_WRITE)) return false;
  245. return file.truncate(length);
  246. }