Posted on by

For those who don’t know what LFS is, it’s a popular Lua library that allows you to perform common file system activities that can’t normally be done in plain Lua. Things like getting file attributes, creating and removing directories (folders), and iterating over files in a directory are all things that can be easily done using LFS.

During the course of this tutorial, it might help to have a separate tab open with the LFS Reference.

Directory Scanning

Let’s say you were creating a note-taking app that allows users to create, save, and read text-based notes that are all saved to system.DocumentsDirectory. Sure, it’s easy to keep track of what the user does inside of your app. You could simply keep your own record of the notes within a “notes” table and update it whenever something is added or removed from the app’s Documents folder.

But what if you wanted to enable file-sharing through the iTunes interface so users can import and export their notes? The problem with that is, since the user is adding (and possibly removing) files to the Documents folder of your app bundle from outside of your app, the table you’re using to keep track of available notes is going to be inaccurate.

Here’s where LuaFileSystem would come in really handy. Every time your app is launched, you can use LFS to scan the contents of system.DocumentsDirectory and import any new notes! You could do this as much as you needed to ensure you have an accurate account of exactly what is inside that folder. Of course, that’s just one example where you might use this functionality. As with everything, it all boils down to the individual needs of your app.

Here’s an example of how to iterate over the contents of the app’s Documents directory using a simple for-loop:

local lfs = require "lfs"

local doc_path = system.pathForFile( "", system.DocumentsDirectory )

for file in lfs.dir(doc_path) do
   --file is the current file or directory name
   print( "Found file: " .. file )
end

Adding Folders

One of the things most commonly requested with Corona’s Documents, Temporary, and Cache folders is the ability to add new directories (e.g. folders) within them for easier organization.

If your app downloads several external assets and you would like to organize different types of files into different folders (or are working with lots of files with similar or same file names), being able to add and remove folders is something that’s absolutely essential.

Thankfully, LFS makes this easy as well. First, you’ll need to change the “current directory” to where you want to place the folder using lfs.chdir(), and then you’ll use lfs.mkdir() to actually create the directory.

local lfs = require "lfs"

-- get raw path to app's Temporary directory
local temp_path = system.pathForFile( "", system.TemporaryDirectory )

-- change current working directory
local success = lfs.chdir( temp_path ) -- returns true on success
local new_folder_path

if success then
   lfs.mkdir( "MyNewFolder" )
   new_folder_path = lfs.currentdir() .. "/MyNewFolder"
end

What about deleting folders?

If you need to remove (delete) a directory, it is recommended you use the existing os.remove() function to do so. While lfs.rmdir() can only remove directories, os.remove() can handle both.

Timestamps

Another thing you might need your app to do periodically is check the “last modified” timestamp of certain files, especially if you’re implementing any kind of syncing functionality, or even something as simple as keeping track of when the user last loaded a specific file (but didn’t necessarily change it).

Setting a new timestamp

Let’s say we have a file called “mydata.txt” inside of system.TemporaryDirectory. The user wants to view the file, but we want to set the timestamp for when the user last read the file (not just the last time they wrote to it).

In that case, we would simply “touch” the file. In doing so, we set the “last modified” timestamp to today/now. You can also set a custom “access time” and “modification time” with two additional function arguments, or leave them blank to use the current time.

local lfs = require "lfs"

local file_path = system.pathForFile( "mydata.txt", system.TemporaryDirectory )

-- touch the file
lfs.touch( file_path )

Retrieving a timestamp for an existing file

Now, later on, let’s find out when the file was last modified. You can either use the “access” or “modification” property, but if you’re going by the previous example, they would both equal the same thing.

local lfs = require "lfs"

local file_path = system.pathForFile( "mydata.txt", system.TemporaryDirectory )

-- get last modified time
local file_attr = lfs.attributes( file_path )
local last_mod = file_attr.modification

print( last_mod )

LuaFileSystem can do more things than what I showed you here, but chances are, your uses for it in a mobile app will fall into one of the three things I mentioned here. Fortunately, just about all of the LFS functions are straight-forward and easy to use. Please see the LFS Reference page for a complete listing of available functions and syntax information for each one.


Posted by . Thanks for reading...

10 Responses to “Tutorial: LuaFileSystem (LFS)”

  1. Simon

    Ha! I was just looking for a way to scan directories and ended up logging each file downloaded so I knew what was in the Docs directory. If only this came 3 weeks earlier…

    Reply
  2. Dewey

    Seems like this won’t work for any files in the ResourceDirectory…..

    For example, if you want to build an inventory (table) of image assets, then
    system.pathForFile( “”, system.ResourceDirectory )
    will return nil, rather than a starting directory (which LFS requires as a string).

    Do we have an api to get a path to a directory in Resources (rather than docs/temp)??
    I can just temporarily copy my images to Docs unless anyone else has found a way around this??
    Thx
    Dewey

    Reply
  3. David MEKERSA

    Thanks for sharing this Jonathan. I’m wondering if I can use this on Android to allow a user to add (manually) mp3 files to the document directory, and to play them with Corona.

    My need is to allow an Android user to play an mp3 of his choice (not pre-installed with the app). On iOS I can use the iTunes plugin to play external mp3, but it’s not available on Android. So I’m looking for another way.

    My plan B was to ask the Android users to copy their mp3 in the document directory of the app. But I cannot see where the document directory of my Corona app is…

    Any idea?

    Reply

Leave a Reply

  • (Will Not Be Published)