store file in subfolder of documentsDirectory

Dear Corona community,

what I’d like to do:

Download a file via network.download and store it in a subfolder of DocumentsDirectory for later access

what I’ve done so far:

Exactly this:

network.download(link, "POST", function(event) -- in case of an error if( event.isError ) then -- do something -- expected: download worked elseif(event.phase == "ended") then -- do something else end, "newsPics\\picture.jpg", system.DocumentsDirectory)

Does that work?

In windows simulator, it perfectly creates a new folder “newsPics” and stores the file “picture.jpg” in there. On iOS and Android, it also works, even though I cannot verify that it creates the folder or rather stores a file “newsPics\picture.jpg” in DocumentsDirectory. I can access the file via display.newImage and “newsPics\picture.jpg” as filename parameter no problem.

So why am I asking this question?

It would be great if someone could verify that this method is a valid one for creating a new folder or - if it already exists - just use it and store a file “picture.jpg” in there. Googling for this question says something else. According to the https://coronalabs.com/blog/2013/02/13/faq-wednesday-sub-folder-and-file-access/ I might need Lua File System (LFS).

On all my test devices (iOS and Android) it worked without LFS. Could somebody explain me why? :slight_smile:

Thanks in advance,

Chris

You need to make the folders first.

If you’re using SSK, you would do this:

local path = ssk.files.documents.getPath("newsPics") ssk.util.mkFolder( "path" )

After that, the folder will exist and you can write files to it.

SSK Files Lib Docs: https://roaminggamer.github.io/RGDocs/pages/SSK2/libraries/files/

Thanks roaminggamer. But it seems it works even without explicitely creating the folder first. It works in simulator, on Android and even iOS. My question is: Is this a “bug” or do newer versions just dont require the explicit creation any more?

It is possible that the network module is making those folders for you, but I wouldn’t rely on that being universal across Android and iOS.

i.e. If Corona is doing it for you, then it will work universally, but you may just be seeing the side-effect of some OS-specific library that does the work on Android, iOS, OSX, or on Windows (wherever you are testing this).

It is better, IMHO, to create the folders yourself just in case.

Nobody can 100% guarantee this for you without seeing the source (and the staff surely don’t have time to dig through the myriad of libraries specific to each OS), which is why I suggest caution over hope.

Regarding slashes, always use forward slashes. 

Windows will understand them and you can then avoid the 'special character nonsense you have to deal with if you use backslashes.

Ex:

Always do this:

path/path/path

Yup, by the end of the day - as you say - only staff can guarantee this functionality. Maybe they know even without digging through the library, that’s what I was hoping.

Until someone from staff clarifies this (or not), I should do what you suggest and do it the “normal” way :slight_smile:

Thanks, Ed.

I agree with @roaminggamer, it’s always best to be “safe than sorry”. I don’t believe it’s a good use of engineering time and resources to have them research this when you can either use LFS to check for the presence of the directory and make it if it doesn’t exist. This is all easy to do with LFS and you don’t have to make any assumptions in something that might change in the future anyway.

On a side note, if you’re downloading files from the Internet, Apple will want them to go to system.CachesDirectory instead of system.DocumentsDirectory. The idea is those files don’t need to be backed up to iCloud and if they get removed, they can be re-downloaded. 

Rob

Oh, that’s a good point, didnt know that. Your explanation makes sense, guess I have to change some parts in my code then…

Thanks Rob!

I am afraid I’m too dumb to find out how to check if a folder exists with lfs.

The http://keplerproject.github.io/luafilesystem/manual.html#reference docs dont have a “.exists” or similar function and on corona site https://docs.coronalabs.com/guide/data/LFS/index.html it is indeed explained how to create a new folder, but not how to check its existance.

As a path I can only use system.pathForFile, but not something like system.pathForFolder

The only option I see right now is to loop through all the contents of my CachesDirectory and check for the existance of a folder, but that doesnt seem very clean to me…

What am I doing wrong?

/edit: Got it:

 local path = system.pathForFile(“pictures”, system.CachesDirectory)
 print(lfs.chdir(path))

– prints true if exists, otherwise error

Great!

You need to make the folders first.

If you’re using SSK, you would do this:

local path = ssk.files.documents.getPath("newsPics") ssk.util.mkFolder( "path" )

After that, the folder will exist and you can write files to it.

SSK Files Lib Docs: https://roaminggamer.github.io/RGDocs/pages/SSK2/libraries/files/

Thanks roaminggamer. But it seems it works even without explicitely creating the folder first. It works in simulator, on Android and even iOS. My question is: Is this a “bug” or do newer versions just dont require the explicit creation any more?

It is possible that the network module is making those folders for you, but I wouldn’t rely on that being universal across Android and iOS.

i.e. If Corona is doing it for you, then it will work universally, but you may just be seeing the side-effect of some OS-specific library that does the work on Android, iOS, OSX, or on Windows (wherever you are testing this).

It is better, IMHO, to create the folders yourself just in case.

Nobody can 100% guarantee this for you without seeing the source (and the staff surely don’t have time to dig through the myriad of libraries specific to each OS), which is why I suggest caution over hope.

Regarding slashes, always use forward slashes. 

Windows will understand them and you can then avoid the 'special character nonsense you have to deal with if you use backslashes.

Ex:

Always do this:

path/path/path

Yup, by the end of the day - as you say - only staff can guarantee this functionality. Maybe they know even without digging through the library, that’s what I was hoping.

Until someone from staff clarifies this (or not), I should do what you suggest and do it the “normal” way :slight_smile:

Thanks, Ed.

I agree with @roaminggamer, it’s always best to be “safe than sorry”. I don’t believe it’s a good use of engineering time and resources to have them research this when you can either use LFS to check for the presence of the directory and make it if it doesn’t exist. This is all easy to do with LFS and you don’t have to make any assumptions in something that might change in the future anyway.

On a side note, if you’re downloading files from the Internet, Apple will want them to go to system.CachesDirectory instead of system.DocumentsDirectory. The idea is those files don’t need to be backed up to iCloud and if they get removed, they can be re-downloaded. 

Rob

Oh, that’s a good point, didnt know that. Your explanation makes sense, guess I have to change some parts in my code then…

Thanks Rob!

I am afraid I’m too dumb to find out how to check if a folder exists with lfs.

The http://keplerproject.github.io/luafilesystem/manual.html#reference docs dont have a “.exists” or similar function and on corona site https://docs.coronalabs.com/guide/data/LFS/index.html it is indeed explained how to create a new folder, but not how to check its existance.

As a path I can only use system.pathForFile, but not something like system.pathForFolder

The only option I see right now is to loop through all the contents of my CachesDirectory and check for the existance of a folder, but that doesnt seem very clean to me…

What am I doing wrong?

/edit: Got it:

 local path = system.pathForFile(“pictures”, system.CachesDirectory)
 print(lfs.chdir(path))

– prints true if exists, otherwise error

Great!