2013 年 2 月 13 日
周三常见问题解答:子文件夹和文件访问
现在是星期三,又到了解答常见问题 (FAQ) 的时间。这里有一些关于访问子文件夹和文件的常见问题解答。
1. 如何在“文档”或“临时”目录中创建一个新的子文件夹?
可以使用 Lua 文件系统 (LFS) 将子文件夹添加到目录。资源目录是只读的,无法修改。
以下是如何在“文档”目录中创建一个 Images 文件夹。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
local lfs = require "lfs" -- 获取应用程序“文档”目录的原始路径 local docs_path = system.pathForFile( "", system.DocumentsDirectory ) -- 更改当前工作目录 local success = lfs.chdir( docs_path ) -- 成功时返回 true local new_folder_path local dname = "Images" if success then lfs.mkdir( dname ) new_folder_path = lfs.currentdir() .. "/" .. dname end |
您可以在此处找到有关 LFS 的更多信息。
2. 如何访问(读取或写入)已放置在子文件夹中的文件?
您可以根据您想要对文件执行的操作,通过两种方式访问子文件夹中的文件。如果您想显示图像或播放文件中的声音,您可以将子文件夹名称与文件名连接起来,然后提供基本目录。例如,如果您想在“文档”目录中的 Images 子文件夹中显示 cat.png 文件,请执行以下操作
1 |
local catImage = display.newImage( "Images/cat.png", system.DocumentsDirectory, 0, 0 ) |
请注意,在需要 baseDirectory 参数的 API 调用中(例如,display.newImage、display.newImageRect、audio.loadSound 等),您不使用 system.pathForFile。
如果您想在同一个目录中打开 readme.txt 文件,请使用 system.pathForFile 执行以下操作
1 2 3 |
local path = system.pathForFile( "Images/readme.txt", system.DocumentsDirectory ) local fileHandle = io.open( path ) -- 您现在可以使用 fileHandle:read 或 fileHandle:write 来读取或写入文件。 |
如果文件存在,则 fileHandle 将不会是 nil,这将引出我们的下一个问题。
3. 如何测试文件是否存在于文件夹或子文件夹中?
您可以从代码中调用以下函数,以查看文件是否存在于文件夹或子文件夹中。只需记住在调用此函数之前将子文件夹名称附加到文件名。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
---------------------------------------------------------------------------------- -- doesFileExist -- -- 检查文件是否存在于路径中。 -- -- 输入: name = 文件名 -- path = 文件路径(目录) -- 如果缺少 "path",则默认为 ResourceDirectory。 -- -- 返回:true = 文件存在,false = 未找到文件 ---------------------------------------------------------------------------------- -- function doesFileExist( fname, path ) local results = false local filePath = system.pathForFile( fname, path ) -- 如果文件不存在,并且路径是 ResourceDirectory,则 filePath 将为 nil -- if filePath then filePath = io.open( filePath, "r" ) end if filePath then print( "找到文件 -> " .. fname ) -- 清理我们的文件句柄 filePath:close() results = true else print( "文件不存在 -> " .. fname ) end print() return results end |
以下是如何调用上述函数。
1 2 3 4 5 |
-- 检查 Documents 目录中是否存在文件 local results = doesFileExist( "Images/cat.png", system.DocumentsDirectory ) -- 或者检查 Resource 目录 local results = doesFileExist( "Images/cat.png" ) |
4. 如何将文件复制到子文件夹?
以下函数允许将文件从一个文件夹复制到另一个文件夹。一个常见的用法是将 Resource 目录中包含的文件复制到 Documents 目录。在使用此函数之前,必须创建任何子文件夹(如果它们不存在)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
---------------------------------------------------------------------------------- -- copyFile( src_name, src_path, dst_name, dst_path, overwrite ) -- -- 将源名称/路径复制到目标名称/路径 -- -- 输入: src_name = 源文件名 -- src_path = 文件源路径(目录),对于 ResourceDirectory 为 nil -- dst_name = 目标文件名 -- overwrite = true 表示覆盖文件,false 表示不覆盖 -- -- 返回:false = 创建/复制文件时出错 -- nil = 未找到源文件 -- 1 = 文件已存在(未复制) -- 2 = 文件复制成功 ---------------------------------------------------------------------------------- -- function copyFile( srcName, srcPath, dstName, dstPath, overwrite ) local results = false local srcPath = doesFileExist( srcName, srcPath ) if srcPath == false then -- 源文件不存在 return nil end -- 检查目标文件是否已存在 if not overwrite then if fileLib.doesFileExist( dstName, dstPath ) then -- 不要覆盖文件 return 1 end end -- 将源文件复制到目标文件 -- local rfilePath = system.pathForFile( srcName, srcPath ) local wfilePath = system.pathForFile( dstName, dstPath ) local rfh = io.open( rfilePath, "rb" ) local wfh = io.open( wfilePath, "wb" ) if not wfh then print( "writeFileName 打开错误!" ) return false -- 错误 else -- 从 Resource 目录读取文件并将其写入目标目录 local data = rfh:read( "*a" ) if not data then print( "读取错误!" ) return false -- 错误 else if not wfh:write( data ) then print( "写入错误!" ) return false -- 错误 end end end results = 2 -- 文件已复制 -- 清理文件句柄 rfh:close() wfh:close() return results end |
以下是如何使用复制文件例程将 readme.txt 文件从 Resource 目录复制到 Documents 目录。
1 2 |
copyFile( "readme.txt", nil, "readme.txt", system.DocumentsDirectory, true ) local catImage = display.newImage( "cat.png", system.DocumentsDirectory, 0, 0 ) |
5. 关于文件,Android 有哪些限制?
Corona 中的文件访问基于底层操作系统,它会因平台而异。在 iOS 设备上,可以访问 Resource 目录(main.lua 所在的位置)以及 Documents 和 Temporary 目录中的文件。在 Android 上,访问 Resource 目录是有限的,因为它不是真实的目录,而是文件包含在一个 zip 文件中。Corona 允许使用 audio 和 image API 直接加载图像和音频文件,但使用文件 I/O API 对 Resource 文件的访问有限。
由于在 Android 上的这种限制,如果 Resource 目录中包含想要复制到另一个目录(例如 Documents)的文件,则需要更改资源目录中的文件名,以便可以通过文件 I/O API 访问它。例如,如果想将图像文件从 Resource 移动到 Documents 目录,则必须使用不同的扩展名重命名它,以便可以访问它。我们的 cat.png 文件需要被命名为 cat.png.txt 才能被复制。
以下是在 Android 上将 cat.png 文件复制到 Documents 目录的方法(假设它存储为 cat.png.txt)。
1 2 |
copyFile( "cat.png.txt", nil, "cat.png", system.DocumentsDirectory, true ) local catImage = display.newImage( "cat.png", system.DocumentsDirectory, 0, 100 ) |
在 Android 的 Resource 目录中无法读取的文件扩展名有:html、htm、3gp、m4v、mp4、png、jpg 和 rtf。
上述技术适用于所有平台,所以如果它在 Android 上有效,那么在其他任何地方都有效。
这就是今天的常见问题解答。我希望你们喜欢它们,甚至学到了一些东西。
Jose
发布于 09:27, 2 月 14 日好文章,Tom! 我是从论坛上关于 pathForFile 警告的问题来到这里的 (http://developer.coronalabs.com/forum/2013/02/14/pathforfile-warnings),但我恐怕你的代码也存在同样的问题。
有没有其他方法可以获取文件的存在状态,而跳过 pathForFile 在找不到文件时引起的警告???
无论如何,第 1 点和第 4 点对我的下一个项目非常有帮助,谢谢!
Alberto
发布于 09:38, 2 月 15 日你好!
关于 Android 设备,是否可以创建子文件夹并将文件复制到外部存储?
我的 Android 设备有 2GB 的内部存储和 16GB 的 NAND 闪存。
我正在开发的应用程序允许用户下载大约 1GB 大小的目录,所以我需要使用闪存中的 16GB。
这可能吗?
先感谢了!
Alberto。
Alberto
发布于 01:14, 2 月 19 日另一个问题
我在 system.DocumentsDirectory 中创建了一个子目录,并且我想将文件直接下载到我创建的那个子文件夹中。当我尝试提供 system 基本目录之外的路径时,它会忽略它们并恢复为 system.DocumentsDirectory 的默认值,尽管添加了子目录名称。
是否无法直接下载到我刚刚创建的子文件夹中?
Alberto。
lessmsios
发布于 17:36, 4 月 1 日在 copy 函数中,行
local srcPath = doesFileExist( srcName, srcPath )
会覆盖参数 srcPath。如果你在不重命名该测试的情况下按原样使用此函数,它会抛出错误。