New File System (real files, Large files faster)
Monkey Forums/Monkey Code/New File System (real files, Large files faster)
| ||
This allows you to write to files in the actual filesystem (GLFW only) It also reads files like you were used to in BlitzMax. (all platforms) file size is not limited to the ~300k limit that seemed to be imposed by previous options. This is based off GfKs FileSystem but uses real files, rather than a virtual file system. As such, saving files in HTML5 is not possible. Reading files in HTML5 is possible. Code to write to output folders is based on GreyAlien's work. THINGS TO NOTE: It will write files to the executables .data folder. It also saves the same data to the current project folder by default. Disable this if you are using it in a release. set APP_NAME to the name of the folder your files are in. (for me it was basicgame.data, hence basicgame) Thanks to GfK and GreyAlien! [monkeycode] Strict Import mojo Import os Const APP_NAME:String="basicgame" Const COPY_TO_PROJECT_DATA_FOLDER:Bool=True Class FileStream Extends DataConversion Field filename:String Field fileptr:Int Private Field arrayPointer:int Field data:String Field WriteData:String Field readingOnly:bool Public Function WriteFile:FileStream(filename:String) Local f:FileStream = New FileStream f.filename = filename f.fileptr = 0 f.arrayPointer=0 f.data="" f.readingOnly=False Return f End Function ReadFile:FileStream(filename:String) Local f:FileStream = New FileStream f.filename = filename f.fileptr = 0 Print "Reading from "+filename f.data = app.LoadString(filename) 'LoadState() f.readingOnly=True Return f End Method Close:Void() If (readingOnly=False) Then FlushData() Print "Writing "+Self.WriteData.Length()+" bytes." #If TARGET="glfw" Then SaveString(Self.WriteData,CurrentDir()+"/data/"+filename) 'local to build - Runtime folder. If (COPY_TO_PROJECT_DATA_FOLDER) Then Print "Writing "+CurrentDir()+"/../../../../"+APP_NAME+".data/"+filename SaveString(Self.WriteData,CurrentDir()+"/../../../../"+APP_NAME+".data/"+filename) 'project data path Endif #End Self.data="" Self.WriteData="" Endif End Method ReadInt:Int() Local result:String result = Self.data[Self.fileptr..Self.fileptr+4] Self.fileptr+=4 Return Self.StringToInt(result) End Method WriteInt:Void(val:Int) ' Print(val+" Outputted.") Self.fileptr+=4 Self.data+=Self.IntToString(val) End Method ReadString:String() Local result:String Local strLen:Int = Self.StringToInt(Self.data[Self.fileptr..Self.fileptr+4]) Self.fileptr+=4 If strLen > 0 result = Self.data[Self.fileptr..Self.fileptr+strLen] Self.fileptr+=strLen End Return result End Method WriteString:Void(val:String) Self.data+=Self.IntToString(val.Length()) If val.Length() > 0 Self.data+=val Self.fileptr+=val.Length() End CheckDataLength() End Method ReadFloat:Float() Local result:Float Local s:String Local strLen:Int = Self.StringToInt(Self.data[Self.fileptr..Self.fileptr+4]) Self.fileptr+=4 s = Self.data[Self.fileptr..Self.fileptr+strLen] result = Self.StringToFloat(s) Self.fileptr+=strLen Return result End Method WriteFloat:Void(val:Float) Local s:String = Self.FloatToString(val) Self.data+=Self.IntToString(s.Length()) Self.data+=s CheckDataLength() End Method ReadBool:Bool() Local result:Bool result = Bool(Self.data[Self.fileptr]) Self.fileptr+=1 Return result End Method Method WriteBool:Void(val:Bool) Self.data+=String.FromChar(val) CheckDataLength() End Method Method ReadByte:Int() Local result:Int= Int(Self.data[Self.fileptr]) Self.fileptr+=1 Return (result) End Method WriteByte:Void(val:Int) Self.fileptr+=1 Self.data+=String.FromChar(val & $ff)'Self.ByteToString(val) CheckDataLength() End Method CheckDataLength:void() If (Self.data.Length()>65536) Then '64k round-up Print "Flushed." FlushData() Endif End Method Method FlushData:void() Self.WriteData=Self.WriteData+Self.data Self.data="" End method End Class DataConversion Method IntToString:String(val:Int) Local result:String= String.FromChar((val) & $FF) result+= String.FromChar((val Shr 8) & $FF) result+= String.FromChar((val Shr 16) & $FF) result+= String.FromChar((val Shr 24) & $FF) Return result End Method FloatToString:String(val:Float) Return String(val) End Method StringToInt:Int(val:String) Local result:Int result = (val[0]) result|= (val[1] Shl 8) result|= (val[2] Shl 16) result|= (val[3] Shl 24) Return result End Method StringToFloat:Float(val:String) Return Float(val) End End [/monkeycode] example of use: [monkeycode] Local stream:FileStream=FileStream.WriteFile("Temp.dat") stream.WriteByte(65) stream.WriteByte(66) stream.WriteByte(67) stream.WriteByte(68) stream.WriteByte(69) stream.WriteByte(70) stream.Close() stream=FileStream.ReadFile("Temp.dat") Print stream.ReadByte() Print stream.ReadByte() Print stream.ReadByte() Print stream.ReadByte() Print stream.ReadByte() Print stream.ReadByte() stream.Close() [/monkeycode] |
| ||
use [ monkeycode ] for your code box's will make it look better. |
| ||
nice, dude. Can we use something like this for direct saving/loading of tilemap data? (With the proper file filter directive, of course) |
| ||
Yes you can, but be careful if you release to HTML5- Some browsers struggle to load data files. I'm going to add Base64 (or for speed, base52) encoding to the library shortly to allow for easy HTML5 deployment. |