tfcard_app.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. --[[
  2. @module tfcard_app
  3. @summary TF卡文件操作测试模块
  4. @version 1.0.0
  5. @date 2025.08.25
  6. @author 王棚嶙
  7. @usage
  8. 本文件为TF卡的文件操作测试流程:
  9. 1. 创建目录
  10. 2. 创建并写入文件
  11. 3. 检查文件是否存在
  12. 4. 获取文件大小
  13. 5. 读取文件内容
  14. 6. 启动计数文件操作
  15. 7. 文件追加测试
  16. 8. 按行读取测试
  17. 9. 读取后关闭文件
  18. 10. 文件重命名
  19. 11. 列举目录内容
  20. 12. 删除文件
  21. 13. 删除目录
  22. 本文件没有对外接口,直接在main.lua中require "tfcard_app"就可以加载运行
  23. ]]
  24. -- 开始进行主测试流程。
  25. local function tfcard_main_task()
  26. -- 供电控制 (Air8101专用)
  27. --gpio13为8101TF卡的供电控制引脚,在挂载前需要设置为高电平,不能省略
  28. gpio.setup(13, 1)
  29. -- ########## 开始进行tf卡挂载 ##########
  30. local mount_ok, mount_err = fatfs.mount(fatfs.SDIO, "/sd", 24 * 1000 * 1000)
  31. if mount_ok then
  32. log.info("fatfs.mount", "挂载成功", mount_err)
  33. else
  34. log.error("fatfs.mount", "挂载失败", mount_err)
  35. goto resource_cleanup
  36. end
  37. -- ########## 获取SD卡的可用空间信息并打印。 ##########
  38. data, err = fatfs.getfree("/sd")
  39. if data then
  40. --打印SD卡的可用空间信息
  41. log.info("fatfs", "getfree", json.encode(data))
  42. else
  43. --打印错误信息
  44. log.info("fatfs", "getfree", "err", err)
  45. goto resource_cleanup
  46. end
  47. -- 列出所有挂载点,如不需要,可注释掉。
  48. data = io.lsmount()
  49. log.info("fs", "lsmount", json.encode(data))
  50. -- ########## 功能: 启用fatfs调试模式 ##########
  51. -- 若挂载失败,可以尝试打开调试信息,查找原因.(设置调试模式)
  52. -- fatfs.debug(1)
  53. -- 执行tfcard文件操作演示
  54. log.info("文件操作", "===== 开始文件操作 =====")
  55. dir_path = "/sd/io_test"
  56. -- 1. 创建目录
  57. if io.mkdir(dir_path) then
  58. log.info("io.mkdir", "目录创建成功", "路径:" .. dir_path)
  59. else
  60. -- 检查是否目录已存在
  61. if io.exists(dir_path) then
  62. log.warn("io.mkdir", "目录已存在,跳过创建", "路径:" .. dir_path)
  63. else
  64. log.error("io.mkdir", "目录创建失败且目录不存在", "路径:" .. dir_path)
  65. goto resource_cleanup
  66. end
  67. end
  68. -- 2. 创建并写入文件
  69. file_path = dir_path .. "/boottime"
  70. file = io.open(file_path, "wb")
  71. if file then
  72. file:write("这是io库API文档示例的测试内容")
  73. file:close()
  74. --在LuatOS文件操作中,执行file:close()是必须且关键的操作,它用于关闭文件句柄,释放资源,并确保数据被正确写入磁盘。
  75. -- 如果不执行file:close(),可能会导致数据丢失、文件损坏或其他不可预测的问题。
  76. log.info("文件创建", "文件写入成功", "路径:" .. file_path)
  77. else
  78. log.error("文件创建", "文件创建失败", "路径:" .. file_path)
  79. goto resource_cleanup
  80. end
  81. -- 3. 检查文件是否存在
  82. if io.exists(file_path) then
  83. log.info("io.exists", "文件存在", "路径:" .. file_path)
  84. else
  85. log.error("io.exists", "文件不存在", "路径:" .. file_path)
  86. goto resource_cleanup
  87. end
  88. -- 4. 获取文件大小
  89. file_size = io.fileSize(file_path)
  90. if file_size then
  91. log.info("io.fileSize", "文件大小:" .. file_size .. "字节", "路径:" .. file_path)
  92. else
  93. log.error("io.fileSize", "获取文件大小失败", "路径:" .. file_path)
  94. goto resource_cleanup
  95. end
  96. -- 5. 读取文件内容
  97. file = io.open(file_path, "rb")
  98. if file then
  99. content = file:read("*a")
  100. log.info("文件读取", "路径:" .. file_path, "内容:" .. content)
  101. file:close()
  102. else
  103. log.error("文件操作", "无法打开文件读取内容", "路径:" .. file_path)
  104. goto resource_cleanup
  105. end
  106. -- 6. 启动计数文件操作
  107. count = 0
  108. --以只读模式打开文件
  109. file = io.open(file_path, "rb")
  110. if file then
  111. data = file:read("*a")
  112. log.info("启动计数", "文件内容:", data, "十六进制:", data:toHex())
  113. count = tonumber(data) or 0
  114. file:close()
  115. else
  116. log.warn("启动计数", "文件不存在或无法打开")
  117. end
  118. log.info("启动计数", "当前值:", count)
  119. count=count + 1
  120. log.info("启动计数", "更新值:", count)
  121. file = io.open(file_path, "wb")
  122. if file then
  123. file:write(tostring(count))
  124. file:close()
  125. log.info("文件写入", "路径:" .. file_path, "内容:", count)
  126. else
  127. log.error("文件写入", "无法打开文件", "路径:" .. file_path)
  128. goto resource_cleanup
  129. end
  130. -- 7. 文件追加测试
  131. append_file = dir_path .. "/test_a"
  132. -- 清理旧文件
  133. os.remove(append_file)
  134. -- 创建并写入初始内容
  135. file = io.open(append_file, "wb")
  136. if file then
  137. file:write("ABC")
  138. file:close()
  139. log.info("文件创建", "路径:" .. append_file, "初始内容:ABC")
  140. else
  141. log.error("文件创建", "无法创建文件", "路径:" .. append_file)
  142. goto resource_cleanup
  143. end
  144. -- 追加内容
  145. file = io.open(append_file, "a+")
  146. if file then
  147. file:write("def")
  148. file:close()
  149. log.info("文件追加", "路径:" .. append_file, "追加内容:def")
  150. else
  151. log.error("文件追加", "无法打开文件进行追加", "路径:" .. append_file)
  152. goto resource_cleanup
  153. end
  154. -- 验证追加结果
  155. file = io.open(append_file, "r")
  156. if file then
  157. data = file:read("*a")
  158. log.info("文件验证", "路径:" .. append_file, "内容:" .. data, "结果:",
  159. data == "ABCdef" and "成功" or "失败")
  160. file:close()
  161. else
  162. log.error("文件验证", "无法打开文件进行验证", "路径:" .. append_file)
  163. goto resource_cleanup
  164. end
  165. -- 8. 按行读取测试
  166. line_file = dir_path .. "/testline"
  167. file = io.open(line_file, "w")
  168. if file then
  169. file:write("abc\n")
  170. file:write("123\n")
  171. file:write("wendal\n")
  172. file:close()
  173. log.info("文件创建", "路径:" .. line_file, "写入3行文本")
  174. else
  175. log.error("文件创建", "无法创建文件", "路径:" .. line_file)
  176. goto resource_cleanup
  177. end
  178. -- 按行读取文件
  179. file = io.open(line_file, "r")
  180. if file then
  181. log.info("按行读取", "路径:" .. line_file, "第1行:", file:read("*l"))
  182. log.info("按行读取", "路径:" .. line_file, "第2行:", file:read("*l"))
  183. log.info("按行读取", "路径:" .. line_file, "第3行:", file:read("*l"))
  184. file:close()
  185. else
  186. log.error("按行读取", "无法打开文件", "路径:" .. line_file)
  187. goto resource_cleanup
  188. end
  189. -- 9. 文件重命名
  190. old_path = append_file
  191. new_path = dir_path .. "/renamed_file.txt"
  192. success, err = os.rename(old_path, new_path)
  193. if success then
  194. log.info("os.rename", "文件重命名成功", "原路径:" .. old_path, "新路径:" .. new_path)
  195. -- 验证重命名结果
  196. if io.exists(new_path) and not io.exists(old_path) then
  197. log.info("验证结果", "重命名验证成功", "新文件存在", "原文件不存在")
  198. else
  199. log.error("验证结果", "重命名验证失败")
  200. end
  201. else
  202. log.error("os.rename", "重命名失败", "错误:" .. tostring(err), "原路径:" .. old_path)
  203. goto resource_cleanup
  204. end
  205. -- 10. 列举目录内容
  206. log.info("目录操作", "===== 开始目录列举 =====")
  207. ret, data = io.lsdir(dir_path, 50, 0) -- 50表示最多返回50个文件,0表示从目录开头开始
  208. if ret then
  209. log.info("fs", "lsdir", json.encode(data))
  210. else
  211. log.info("fs", "lsdir", "fail", ret, data)
  212. goto resource_cleanup
  213. end
  214. -- 11. 删除文件测试
  215. -- 测试删除renamed_file.txt文件
  216. if os.remove(new_path) then
  217. log.info("os.remove", "文件删除成功", "路径:" .. new_path)
  218. -- 验证renamed_file.txt删除结果
  219. if not io.exists(new_path) then
  220. log.info("验证结果", "renamed_file.txt文件删除验证成功")
  221. else
  222. log.error("验证结果", "renamed_file.txt文件删除验证失败")
  223. end
  224. else
  225. log.error("io.remove", "renamed_file.txt文件删除失败", "路径:" .. new_path)
  226. goto resource_cleanup
  227. end
  228. -- 测试删除testline文件
  229. if os.remove(line_file) then
  230. log.info("os.remove", "testline文件删除成功", "路径:" .. line_file)
  231. -- 验证删除结果
  232. if not io.exists(line_file) then
  233. log.info("验证结果", "testline文件删除验证成功")
  234. else
  235. log.error("验证结果", "testline文件删除验证失败")
  236. end
  237. else
  238. log.error("io.remove", "testline文件删除失败", "路径:" .. line_file)
  239. goto resource_cleanup
  240. end
  241. if os.remove(file_path) then
  242. log.info("os.remove", "文件删除成功", "路径:" .. file_path)
  243. -- 验证删除结果
  244. if not io.exists(file_path) then
  245. log.info("验证结果", "boottime文件删除验证成功")
  246. else
  247. log.error("验证结果", "boottime文件删除验证失败")
  248. end
  249. else
  250. log.error("io.remove", "boottime文件删除失败", "路径:" .. file_path)
  251. goto resource_cleanup
  252. end
  253. -- 12. 删除目录(不能删除非空目录,所以在删除目录前要确保目录内没有文件或子目录)
  254. if io.rmdir(dir_path) then
  255. log.info("io.rmdir", "目录删除成功", "路径:" .. dir_path)
  256. -- 验证删除结果
  257. if not io.exists(dir_path) then
  258. log.info("验证结果", "目录删除验证成功")
  259. else
  260. log.error("验证结果", "目录删除验证失败")
  261. end
  262. else
  263. log.error("io.rmdir", "目录删除失败", "路径:" .. dir_path)
  264. goto resource_cleanup
  265. end
  266. log.info("文件操作", "===== 文件操作完成 =====")
  267. -- ########## 功能: 收尾功能演示##########
  268. -- 卸载文件系统
  269. ::resource_cleanup::
  270. log.info("结束", "开始执行关闭操作...")
  271. -- 如已挂载需先卸载文件系统
  272. if mount_ok then
  273. if fatfs.unmount("/sd") then
  274. log.info("文件系统", "卸载成功")
  275. else
  276. log.error("文件系统", "卸载失败")
  277. end
  278. end
  279. end
  280. sys.taskInit(tfcard_main_task)