Skip to content

183. Reading and writing data files

November 17, 2014

This time, I’m highlighting a nice utility written by SkyTheCoder, posted on the Codea forum (partly) here, and here. He explains it as follows

I experimented with sound & music downloading/playing when Codea 2.0 came out. I found you could http.request a sound file, take the data it returned (first parameter in success function) and write it to a .wav or .mp3 file in your assetpacks. I also made an easy writeFile function to make the sound/music file.

This works for data as well as sound/music, so I’ll try it out in this post, and share the code with you.

So here is Sky’s file code, which uses standard Lua file output/input commands.

function writeFile(fileName, data)
    local file = os.getenv("HOME") .. "/Documents/Dropbox.assetpack/" .. fileName
    wFd, err = io.open(file, "w")
    if wFd == nil then
        error("\n\nError creating/editing file " .. fileName .. "\n\nError: " .. err)
    end
    wFd:write(data)
    wFd:close()
    print("File " .. fileName .. " installed!")
end

function readFile(fileName)
    local file = os.getenv("HOME") .. "/Documents/Dropbox.assetpack/" .. fileName
    rFd, err = io.open(file, "r")
    if rFd == nil then
        error("\n\nError reading file " .. fileName .. "\n\nError: " .. err)
    end
    local ret = rFd:read("*all")
    rFd:close()
    return ret
end

What it does

You pass writeFile a filename (including a file extension like .mp3 in the case of music) and the data, and it stores it in the iPad folder which is linked to your Dropbox account.

If you use writeFile, the file won’t come up in your list of Codea assets, nor will it be uploaded to your internet Dropbox account. At this stage, the only way to get it back is with readFile. 

However, once you sync Dropbox within Codea (ie go into the Dropbox folder for your images or music and press the sync button), your file will be available within Codea, and it will be uploaded to your Dropbox account.

This is probably confusing, so I’ll explain a little more.

  • Lua is the language underneath Codea, and the writeFile and readFile functions are written in Lua.
  • Codea has its own file management system which it updates when you use Codea commands
  • If you store data in the iPad Dropbox folder with writeFile, which uses Lua and not Codea, then Codea won’t know about that data, and you can’t use the data with any Codea commands like music
  • This doesn’t matter for text files, because you don’t need Codea – you can use readFile to get the data back
  • when you manually sync with Dropbox, Codea will “discover” your data files, and then you can use Codea commands like music and readImage with them

I’m going to try storing and reading back three files – a text, image, and music file.

Text

This code will test whether we can store and recover text. I’ve included a lot of the unusual symbols just to see if they work.

str="The quick brown Fox =!@#$%^,;:.&*?/\+-<> 12345678"
writeFile("test.txt",str)
str1=readFile("test.txt")
if str1==str then print("String test pass") else print("String test fail") end

It passes. So we can write and then read text easily enough, and because we don’t need to use normal Codea commands to read the data from the file, there is no need to sync our Dropbox folder (unless we want to upload the text to the online Dropbox account and view it there, eg using a desktop computer).

Music

Storing music is a little trickier, if we need to download it first, but this is still a great way to import music into a Codea project.
First, I need to use http.request to download the music file into memory. This is asynchronous, that is, it will happen when the internet feels like responding, so we provide a callback function (explanation here)
function DownloadMusic(url,name)   
    http.request(url,function(d) writeFile(name,d) end)
end

So if we run DownloadMusic with the url for a music file (eg this), and give it a name (eg “bats.mp3”), it will save it in our iPad’s linked Dropbox folder, using writeFile. We can read this data back with readFile, but we can’t play it from that, ie this doesn’t work

m=readFile("bats.mp3") --read music data
music(m) --won't play

To play it, you need to sync your Dropbox account in Codea, then you can just play it by writing music(“Dropbox:bats”).

 Images

This is fairly similar to downloading music, but there are differences. Again, you use http.request to fetch the image data. To save it as an image, there is a special Codea command saveImage, so we don’t need writeFile for that. (We need to add “Dropbox:” on the beginning of the file name, because saveImage won’t do that for us).

function DownloadImage(url,name)   
    http.request(url,function(d) saveImage("Dropbox:"..name,d) end)
end

Once your image is saved, it can be used straight away by Codea, without the need to sync it first – because we used Codea to save it, rather than a Lua save file command.

 Summary

These functions can be very useful for storing and recovering text data, and also for downloading and storing music. They aren’t needed for storing images.

From → Graphics, Programming

One Comment

Trackbacks & Pingbacks

  1. Index of posts | coolcodea

Leave a comment