io.open issues with path for file & mac/win inconsistencies

I have this code to save a table as JSON

function File:Save(data, filename)  
 if (not filename) then print('FileIO REQUIRES filename'); return 0 end  
 local path = system.pathForFile( filename, system.DocumentsDirectory )  
 local fl, errstr = io.open(path, "w" )  
  
 if fl then  
 local contents = json.encode(data)  
 fl:write(contents)  
 io.close(fl)  
 else print('ERROR SAVING FILE\>\> ' .. errstr) end  
end  

For some reason this code does not work. If I change to io.open(“out.json”, “w”) it ends up working fine, and I get the out.json file in my project folder on Windows. On Mac, I don’t get anything either way.

I am wondering why system.pathForFile isn’t working for io.open in this call but the function works perfectly if you hard code the filename in the io.open().

I am also wondering why I am getting inconsistent results between Windows 7 Pro x64 and Mac OS X 10.8.2. Windows I can get the function to work by using a hard coded file name rather than using the pathForFile() but on Mac that doesn’t work.

[import]uid: 160288 topic_id: 33790 reply_id: 333790[/import]

On the Mac, your files are written to:

/Users/yourhomedirectory/Library/Application Support/Corona Simulator/yourappname-SOMEREALLYLONGSTRINGWITHNUMBERS/Documents

for the system.DocumentsDirectory. For system.CachesDirectory it’s:

/Users/yourhomedirectory/Library/Application Support/Corona Simulator/yourappname-SOMEREALLYLONGSTRINGWITHNUMBERS/Caches

Then if there is a difference using the filename variable and a hardcoded string, make sure filename is a string and it doesn’t contain any whacky characters.

[import]uid: 199310 topic_id: 33790 reply_id: 134317[/import]

Ok, I found it on the Mac, wow that directory structure is brutal with a ton of apps in there, I had to dump the folder and re-run it to find what I was looking for.

As for the string. I used path to file as you can see in the code.
It doesn’t work as is, but if I change this line:

 local fl, errstr = io.open(path, "w" )  

to be

 local fl, errstr = io.open("out.json", "w" )  

It works, I have confirmed filename is in fact “out.json” via the debugger and print statement. So it should be the same. [import]uid: 160288 topic_id: 33790 reply_id: 134324[/import]

You are basically doing what I do in my saveTable function in the Community code:

function M.saveTable(t, filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local file = io.open(path, "w")  
 if file then  
 local contents = json.encode(t)  
 file:write( contents )  
 io.close( file )  
 return true  
 else  
 return false  
 end  
end  

The only way this fails is if filename is invalid like an empty string or nil or has invalid characters in it. I would drop a print statement at the top of your function to make sure filename is a string and it’s what you’re expecting.

print(filename, type(filename) [import]uid: 199310 topic_id: 33790 reply_id: 134329[/import]

My output is

out.json string

What I expect it would be.

I put this at line 2 right after the function starts to see the input. [import]uid: 160288 topic_id: 33790 reply_id: 134331[/import]

I have a load function, and it works perfectly. Very similar. [import]uid: 160288 topic_id: 33790 reply_id: 134332[/import]

I’ve stepped through the command line debugger and it is going in the function and everything “seems” fine, no errors. [import]uid: 160288 topic_id: 33790 reply_id: 134333[/import]

Do you ever print out errstr to see what it has to say? [import]uid: 199310 topic_id: 33790 reply_id: 134334[/import]

“nil” [import]uid: 160288 topic_id: 33790 reply_id: 134336[/import]

Nevermind, it is working.

I guess the output location is different for Documents is different on Windows as well.
I noticed there is a Simulator/Sandbox directory that has the files.

I didn’t realize it created files in a different location, this would explain why I wasn’t getting any errors.

I guess the difference is, when using DocumentsDirectory it is putting under this sandbox location, if I use “out.json” it is just dropping it in the local directory.

Thank you for your help. Looks like it was user error. [import]uid: 160288 topic_id: 33790 reply_id: 134340[/import]

On the Mac, your files are written to:

/Users/yourhomedirectory/Library/Application Support/Corona Simulator/yourappname-SOMEREALLYLONGSTRINGWITHNUMBERS/Documents

for the system.DocumentsDirectory. For system.CachesDirectory it’s:

/Users/yourhomedirectory/Library/Application Support/Corona Simulator/yourappname-SOMEREALLYLONGSTRINGWITHNUMBERS/Caches

Then if there is a difference using the filename variable and a hardcoded string, make sure filename is a string and it doesn’t contain any whacky characters.

[import]uid: 199310 topic_id: 33790 reply_id: 134317[/import]

Ok, I found it on the Mac, wow that directory structure is brutal with a ton of apps in there, I had to dump the folder and re-run it to find what I was looking for.

As for the string. I used path to file as you can see in the code.
It doesn’t work as is, but if I change this line:

 local fl, errstr = io.open(path, "w" )  

to be

 local fl, errstr = io.open("out.json", "w" )  

It works, I have confirmed filename is in fact “out.json” via the debugger and print statement. So it should be the same. [import]uid: 160288 topic_id: 33790 reply_id: 134324[/import]

You are basically doing what I do in my saveTable function in the Community code:

function M.saveTable(t, filename)  
 local path = system.pathForFile( filename, system.DocumentsDirectory)  
 local file = io.open(path, "w")  
 if file then  
 local contents = json.encode(t)  
 file:write( contents )  
 io.close( file )  
 return true  
 else  
 return false  
 end  
end  

The only way this fails is if filename is invalid like an empty string or nil or has invalid characters in it. I would drop a print statement at the top of your function to make sure filename is a string and it’s what you’re expecting.

print(filename, type(filename) [import]uid: 199310 topic_id: 33790 reply_id: 134329[/import]

My output is

out.json string

What I expect it would be.

I put this at line 2 right after the function starts to see the input. [import]uid: 160288 topic_id: 33790 reply_id: 134331[/import]

I have a load function, and it works perfectly. Very similar. [import]uid: 160288 topic_id: 33790 reply_id: 134332[/import]

I’ve stepped through the command line debugger and it is going in the function and everything “seems” fine, no errors. [import]uid: 160288 topic_id: 33790 reply_id: 134333[/import]

Do you ever print out errstr to see what it has to say? [import]uid: 199310 topic_id: 33790 reply_id: 134334[/import]

“nil” [import]uid: 160288 topic_id: 33790 reply_id: 134336[/import]

Nevermind, it is working.

I guess the output location is different for Documents is different on Windows as well.
I noticed there is a Simulator/Sandbox directory that has the files.

I didn’t realize it created files in a different location, this would explain why I wasn’t getting any errors.

I guess the difference is, when using DocumentsDirectory it is putting under this sandbox location, if I use “out.json” it is just dropping it in the local directory.

Thank you for your help. Looks like it was user error. [import]uid: 160288 topic_id: 33790 reply_id: 134340[/import]