TextOutputStream giving error even though FolderItem is there.

I’ve come to my wits end on this one.

Just trying to create a simple folder and a file in the folder, and it keeps crashing on me. NilObjectException.

[code]Dim prefs As FolderItem = SpecialFolder.ApplicationData.child(“DALE”)
Dim prefs2 As FolderItem = prefs.child(“Preferences.txt”)

If prefs2 <> nil then
prefs2.delete
end

if prefs.exists then
else
prefs.CreateFolder
end

'break

Dim t as TextOutputStream
t = TextOutputStream.Open(prefs2)
t.Writeline(PREF_PACK_NAME.text)
t.Close[/code]

Here’s what’s weird. If I put a break in the code, I can confirm that the folder (prefs) is there, but then it still crashes when trying to create the file (prefs2). If I re-launch the app and try it again, it works perfectly fine. Also, if I create the folder ahead of time, it works perfectly fine.

So, it’s crashing when the app creates the folder…and only on the first time. Very weird

Any ideas?

the creation of PREF2 is dependant on the creation or existance of PREFS.

The only thing you do with PREFS2 is delete it if it exists… but if PREFS does NOT exist, the PREF2 is nil no matter what you do.

Dim prefs As FolderItem = SpecialFolder.ApplicationData.child("DALE")

if not  prefs.exists and prefs<>nil  then prefs.CreateFolder

Dim prefs2 As FolderItem = prefs.child("Preferences.txt")

If prefs2 <> nil then  prefs2.delete

[quote=473566:@Dave S]the creation of PREF2 is dependant on the creation or existance of PREFS.

The only thing you do with PREFS2 is delete it if it exists… but if PREFS does NOT exist, the PREF2 is nil no matter what you do.

[code]
Dim prefs As FolderItem = SpecialFolder.ApplicationData.child(“DALE”)

if not prefs.exists and prefs<>nil then prefs.CreateFolder

Dim prefs2 As FolderItem = prefs.child(“Preferences.txt”)

If prefs2 <> nil then prefs2.delete
[/code][/quote]

t = TextOutputStream.Open(prefs2) creates the file if it doesn’t exist. I’ve used it dozens of times, including elsewhere in the same app.

That may be so, but prefs2 probably exists then. As Dave said, if prefs doesnt exist on line 2 pref2 will be nill all the way through the code and still be nil when you call the Open which will cause the NOE on the Open line. It works the second time or when you create the folder because prefs2 will be set correctly as the “DALE” folder is there.

Yes it would… IF the order of your statements was correct, which it is not

Dim prefs As FolderItem = SpecialFolder.ApplicationData.child("DALE") //if doesn't exist its NIL
Dim prefs2 As FolderItem = prefs.child("Preferences.txt")// because PREFS is NIL, then so is PREFS2

If prefs2 <> nil then // Nothing happens because Pref2 is NIL
  prefs2.delete
end

if prefs.exists then
else
  prefs.CreateFolder // Now Prefs DOES exist, but PREFS2 is STILL NIL
end

[quote=473565:@Niles Mitchell]If prefs2 <> nil then
prefs2.delete
end
[/quote]
Not nil doesn’t mean it exists. It just means it is a folderitem object that points to a location that may or may not exist on disk.

If prefs2<>nil and prefs2.exists then prefs2.delete end if

I think you misspoke. prefs will be non-nil, but if it doesn’t exist, prefs2 will be nil as it represents an impossible path.

Always do file path related operations one step at a time.

It’s crashing on the "t = TextOutputStream.Open(prefs2) " and that’s what we need to concentrate on.

Like I said earlier, I have confirmed with the break that the folder (prefs named “Dale”) is successfully created, and yet the program still crashes when trying to create the prefs2 file (named Preferences.txt)
When I run it again, it creates the file (prefs2 named “Preferences”). Also, if I create the folder manually first, it works.

So it has nothing to with prefs2 not being there. The Open command for TextInputStream will create it if it’s not there. I use it all the time for this purpose.

So, why in this example is it not working?

It doesn’t matter that the DALE folder is created when the line

Dim prefs2 As FolderItem = prefs.child("Preferences.txt")

happens before that folder is created.

That’s just setting the variable, not creating the folder.

It’s actually doing a lot more than that.

It’s attempting to create a FolderItem, but it cannot because the DALE folder has not been created yet. Therefore, prefs2 returns nil.

Restructure the code as we’ve been trying to tell you

Dim prefs As FolderItem = SpecialFolder.ApplicationData.child("DALE")

if prefs.exists then
else
  prefs.CreateFolder
end

Dim prefs2 As FolderItem = prefs.child("Preferences.txt")

If prefs2 <> nil AND prefs2.exists then
  prefs2.delete
end

Dim t as TextOutputStream
t = TextOutputStream.Open(prefs2)
t.Writeline(PREF_PACK_NAME.text)
t.Close
Dim prefs As FolderItem = SpecialFolder.ApplicationData.child("DALE")

sets prefs to the location of the DALE folder, it doesn’t matter if it exists or not at this point. This will never be Nil as the ApplicationData folder always exists (unless something critical has happened to your OS install). So for all intents and purposes prefs will never be Nil

Dim prefs2 As FolderItem = prefs.child("Preferences.txt")

sets prefs2 to the location of a file inside DALE called Preferences.txt if DALE doesn’t exist at this point, this assignment will be Nil. This happens because you’re using prefs.child which will check for the existence of the folderitem pointed to by prefs which doesn’t exist yet. If DALE doesn’t exist at this point prefs2 will be Nil because it can’t physically create a FolderItem to a child of a folder that doesn’t exist and it doesn’t matter that you create that folder later, that check only happens here.

This is exactly the same as the following line of code, but might make why it doesn’t work a little clearer:

Dim prefs2 As FolderItem = SpecialFolder.ApplicationData.child("DALE").child("Preferences.txt")

but is not best practice because the reason for this line failing could be because of multiple reasons and its usually best to “walk the path” and check at each junction.

Put code to check aainst error(s) is a good idea too.

As I stated…I did.

[quote=473591:@Tim Hare]It’s actually doing a lot more than that.

It’s attempting to create a FolderItem, but it cannot because the DALE folder has not been created yet. Therefore, prefs2 returns nil.

Restructure the code as we’ve been trying to tell you

[code]
Dim prefs As FolderItem = SpecialFolder.ApplicationData.child(“DALE”)

if prefs.exists then
else
prefs.CreateFolder
end

Dim prefs2 As FolderItem = prefs.child(“Preferences.txt”)

If prefs2 <> nil AND prefs2.exists then
prefs2.delete
end

Dim t as TextOutputStream
t = TextOutputStream.Open(prefs2)
t.Writeline(PREF_PACK_NAME.text)
t.Close
[/code][/quote]

Thanks Tim and Dave

I had misread Dave’s post earlier.

Still odd where it was erring at, but oh well.

Thanks again!

I do not saw any…

Drats !

FolderItem.LastErrorCode disappears in API2 ?

Try / Catch / End Try is still here !

[quote=473721:@Emile Schwarz]I do not saw any…

Drats !

FolderItem.LastErrorCode disappears in API2 ?

Try / Catch / End Try

FolderItem.LastErrorCode is still there, just deprecated. As the documentation says you should use IOException (http://documentation.xojo.com/api/exceptions/ioexception.html) instead.

Having said that, an exception should be exactly that. If you take care to check for potential issues before they arise, like creating a folder if it doesn’t yet exist before trying to create a file within that folder, such an exception would rarely occur.

Not in the page: http://documentation.xojo.com/api/files/folderitem.html

And I do not saw any error/IOException management in the shared code.

That is what I wanted to say.

Yes this is slowly becoming the norm where documentation doesn’t even mention that exceptions can occur when using a feature. To see that FolderItem can raise an IOException you would have to look closely at all sample code at the end of the page where an example of it is hidden and is only used in some cases. This is why I put in feedback://showreport?report_id=57720 a long time ago but its a big job to get 100% accurate so will probably never get done :frowning:

Not only that Juian, but we can also read code like .Child("test").Child("Test") , etc.

In TextOutputStream too, error code is missing in example.

That is very bad for API2 new comers :wink: