Reading from text files, config files and similar

Monkey Forums/Monkey Code/Reading from text files, config files and similar

matty(Posted 2011) [#1]
Here is a simple program & class I use to parse my text files, hopefully you may find it useful.



Class "TextFile"


Example


Sample test file which needs to be saved as "test.txt" in .data folder



c.k.(Posted 2011) [#2]
In the text file, you could store it as

x=#1 ' this will give you a float
y=%123.3 ' this will give you an integer
colour=red ' this is automatically a string
z="75040" ' this is a string
a=75040 'this is a string

So even though the file is all text, when you load it, you get the original values of your variables.

I'd be surprised if something like this wasn't already available actually.


matty(Posted 2011) [#3]
I was surprised too that I couldn't find anything like this anywhere for monkey already! (which is why I made my own - but I'm happy to be pointed to an existing solution for Monkey).


Earok(Posted 2011) [#4]
Just a quick query - why not use split?

Local lines:String[] = LoadString(fileName).Split("~n")

For Local line:String = Eachin lines
     Local values:String[] = line.Split("=")
     print "Key:" + values[0]
     print "Value:" + values[1]
Next



xzess(Posted 2011) [#5]
Hey thanks pretty nice solution.

I made this from your ideas

Class FileIO
	Field FileContent:String
	Field lines:String[]

	
	Method SaveValue(Key:String,Value:String)
	FileContent += (Key+"="+Value + "~n")
	End
	
	Method GetValue:String(Key:String)
		 lines = LoadState.Split("~n")
		
		For Local line:String = Eachin lines
		     Local values:String[] = line.Split("=")
		     
			 If(values[0] = Key)
			 Return values[1]
			 End
		Next
		
		
	End
	
	Method SaveAll()
	SaveState(FileContent)
	End
End


Save some vars:
Field File:FileIO

Method OnCreate()
 File = New FileIO
 File.Save("Test","Apple")
 File.Save("Test2","Pie")
 File.SaveAll()
End


Load those vars:
Field File:FileIO
Field Str:String
Method OnCreate()
 File = New FileIO
 Str = File.GetValue("Test2")
End



Skn3(Posted 2011) [#6]
In the config examples that comes with monkey there is an XML parser if that is any help. There is also an updated version here: http://www.monkeycoder.co.nz/Community/post.php?topic=326&post=2369


xzess(Posted 2011) [#7]
Thanks man!


Samah(Posted 2011) [#8]
Diddy also has its own XML parser if you were interested.


c.k.(Posted 2012) [#9]
OK, I'm using a FileIO module (who did this?), and want to add a "DeleteKeyPair()" method... Can anybody lend a hand? Thank you! :-)

Import mojo

Class FileIO
	Field FileContent:String
	Field lines:String[]

	Method DeleteKeyPair( Key:String )
		' HOW TO DO THIS PART?!
		' remove a key and its value from FileContent
		' if it doesn't exist, no worries
	End
	
	Method SaveValue(Key:String,Value:String)
		DeleteKeyPair( Key )			' remove any prior key+value pair first
		FileContent += (Key+"="+Value + "~n")	' add this new key+value pair
	End
	
	Method GetValue:String(Key:String)
		lines = LoadState.Split("~n")
		For Local line:String = Eachin lines
		     Local values:String[] = line.Split("=")
			 If(values[0] = Key)
				 Return values[1]
			 End
		Next
		Return ""
	End

	Method GetValue:String(Key:Int)
		lines = LoadState.Split("~n")
		For Local line:Int = 0 to lines.Length - 1
			Print lines[line]
		Next
		Return lines[Key]
	End
	
	Method GetAll:String[]()
		Return LoadState.Split("~n")
	End

	Method GetRaw:String()
		Return LoadState()
	End
	
	Method SaveAll()
		SaveState(FileContent)
	End
	
	Method Destroy()
		SaveState("")
	End
	
End




c.k.(Posted 2012) [#10]
I wrote it. Here it is. Any improvements welcome.

[monkeycode]
Method DeleteValue( Key:String )
Local newFC:String = ""
' remove a key and its value from FileContent
' if it doesn't exist, no worries
lines = GetAll()
If lines.Length() > 0 Then
For Local line:String = Eachin lines
Local values:String[] = line.Split("=")
If values.Length() > 1 Then
If (values[0]<>Key) Then
newFC += (values[0]+"="+values[1]+"~n")
EndIf
Endif
Next
Endif
FileContent = newFC
SaveAll()
End
[/monkeycode]


muddy_shoes(Posted 2012) [#11]
If you intend to use this a lot then you should probably think about the performance issues. As stands you're parsing the data and doing a linear search on every fetch and parsing, searching and then rebuilding it all again on every write/delete (although curiously the code saves after the delete but not after writing an new value).


c.k.(Posted 2012) [#12]
It doesn't happen a lot, and certainly not enough to worry about performance (I think). Here's the full thing I'm using, and it looks like AddValue() does save after the write.

[monkeycode]
Import mojo

Class FileIO
Field FileContent:String
Field lines:String[]

Method OnCreate:VOID()
FileContent = GetAll()
End

Method DeleteValue( Key:String )
Local newFC:String = ""
' remove a key and its value from FileContent
' if it doesn't exist, no worries
lines = GetAll()
If lines.Length() > 0 Then
For Local line:String = Eachin lines
Local values:String[] = line.Split("=")
If values.Length() > 1 Then
If (values[0]<>Key) Then
newFC += (values[0]+"="+values[1]+"~n")
EndIf
Endif
Next
Endif
FileContent = newFC
SaveAll()
End

Method AddValue(Key:String,Value:String)
DeleteValue( Key ) ' remove any prior key+value pair
FileContent += (Key+"="+Value + "~n") ' add this new key+value pair
SaveAll()
End

Method GetValue:String(Key:String)
'lines = LoadState.Split("~n")
lines = GetAll()
For Local line:String = Eachin lines
Local values:String[] = line.Split("=")
If(values[0] = Key)
Return values[1]
End
Next
Return ""
End

Method GetAll:String[]()
Return LoadState.Split("~n")
End

Method GetRaw:String()
Return LoadState()
End

Method SaveAll()
SaveState(FileContent)
End

Method Destroy()
SaveState("")
End

End
[/monkeycode]

Any hints, tips, tricks are welcome. Thanks!


muddy_shoes(Posted 2012) [#13]
Yes, well that's different code to what you posted above. Now you're saving twice when setting a value, once when deleting the old value and then again after adding the new one.

It may not be an issue with how you're using it now, but you should be aware that it will definitely be an issue if you use it for any non-trivial amounts of data, especially on a platform such as Android.