io.write results in zero byte file

I’m trying to write a tiny file (5 bytes) using pathForFile to ApplicationsSupport Directory:

    local path = system.pathForFile("ZC.txt", system.ApplicationSupportDirectory)
    local file, errorString = io.open(path,"w")
    if not file then
        print("File error attempting a write+: " .. errorString)
    else
        print("new zip code : " .. zipcode .. " : written to ZC.txt")
        io.write(zipcode)
        io.close(file)
    end

The end result is a zero byte file. I can watch it create the file ZC.txt (I’ve tried both “w” and “w+”… it makes no difference) in the Sandbox, but the resulting file is always empty. There are no errors.

If I manually edit the file, add a zipcode and then do an io.read, I can read it into my program just fine. I’ve tried this on the Simulator as well as an Android device, with the same results. Any ideas?

  1. Welcome to the community! I must admit. I’ve been here since 2011 and I’ve never used that folder. :slight_smile: It seems like it should work and I’d like to know why it isn’t too. However …
  2. Is there a reason you’re not using one of the more traditional directories like documents or temporary?
  3. If you try the ‘documents’ directory do you have the same issue?

Yes. When I used TemporaryDirectory, same result. When I try DocumentsDirectory, no file shows up anywhere in the Sandbox. BTW, I’ve made sure the Windows directory has full access rights for all users, and it does. So, I’m stumped on something that ought to be dead simple.

In other programming languages, this behavior occurs when one forgets to close the file, but I’ve made sure that “io.close(file)” is in there.

(Being new to Android, I just followed the directions when I chose ApplicationSupportDirectory, as in " Used with system.pathForFile() to create a path for storing and retrieving files that need to persist between application sessions but are not visible to users." … this fit my need to a “T”. )

I also tried non-standard names for path/file/etc in case some of that was reserved, but that didn’t matter either.

If I add another io.close(), then I get a Runtime error stating “attempt to use a closed file”, so I’m reasonably sure the file is closed with that first io.close().

That is really weird.

Please do this for me…

  1. Download this: https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2015/07/persistingData.zip
  2. Run it on your simulator and drag the red character.
  3. Reload the game/restart the simulator.
  4. Did the red character stay where you moved it in step #2?

If, “Yes”. Then my file writing code is working and there is an error in yours (we can address that).
If, “No”. I think you’ve got an issue with your computer/OS blocking the simulator from accessing the disk for writes.

You can build and install this on a device too. You’ll need to run it, move a character, kill the app, and re-run it to test this.

Note: This sample was made long ago for another question, but it is a quick test of the issue.

Yes, it worked on the Simulator… and I can see the file it wrote in the Sandbox.

I see you used a table.save … I am, of course, interested in that but also curious as the why my code – based very closely on the LUA documentation for io* – doesn’t work.

Many thanks!

My code uses io.* to do the table save.

I also have io.* extensions simplifying saving and loading text files:


https://roaminggamer.github.io/RGDocs/pages/SSK2/extensions/#io

You can look at my io.* code and compare it to yours.

Here is my io.* file writing code:

if( io.writeFile ) then
   print("ERROR! io.writeFile() exists already")
else
   function io.writeFile( dataToWrite, fileName, base )
      local base = base or system.DocumentsDirectory

      local fileName = fileName
      if( base ) then
         fileName = system.pathForFile( fileName, base )
      end
      fileName = io.repairPath( fileName )
      local f=io.open(fileName,"wb")
      if (f == nil) then 
         return nil
      end

      f:write( dataToWrite )

      io.close(f)

   end
end

Here is the io.* file reading code:

if( io.readFile ) then
   print("ERROR! io.readFile() exists already")
else
   function io.readFile( fileName, base )
      local base = base or system.DocumentsDirectory
      local fileContents

      if( io.exists( fileName, base ) == false ) then
         return nil
      end

      local fileName = fileName
      if( base ) then
         fileName = system.pathForFile( fileName, base )
      end
      fileName = io.repairPath( fileName )
      local f=io.open(fileName,"rb")
      if (f == nil) then 
         return nil
      end

      fileContents = f:read( "*a" )

      io.close(f)

      return fileContents
   end
end

I see it now. You have this:

        io.write(zipcode)
        io.close(file)

You should have this

        file:write(zipcode)
        io.close(file)

fixed typo above …on last edit

Ok, yeah, dumb error on my part. After changing things to match yours, I then got nothing but errors, but then “saw it”… it should be:

file:write(zipcode)
file:close(file)

…and that works! Thanks so much!

1 Like