HTML5 Filesystem in Smart Mobile Studio
Yesterday I presented a new QTX feature, namely a virtual filesystem which runs in your browser. In short it allows you to create files through an in-memory filesystem, which can then be stored in its totality in local-storage, global-storage or in a browser database.
Well today I can show you an example of how you use this. Here is a short teaser. Notice the use of anonymous records, which is really a fantastic feature of Smart Pascal.
mFileSystem:=TQTXFileSystem.Create(NIL); try mFileSystem.mkDir('first') .mkDir('second') .mkFile('text.txt',null); mFile:=TQTXFileSystemFile(mFileSystem.FindFileObject ('/first/second/text.txt')); if mFile<>NIL then begin mFile.WriteData ( record id:= 12; text:= "this is awesome"; cost:= 12.95 end); writeln(mFile.ReadData.text); end else writeln('invalid path'); finally mFilesystem.free; end;
Im not going to divulge to much about this code. Most Smart Pascal developers will understand what’s going on I believe. But in short:
- mkdir() creates a folder, and returns the folder object
- mkfile() creates a file and returns the file object
- FindFileObject() takes a path and recursively drills down to locate the filesystem-object
- WriteData() stores a variant value in a file
- ReadData() returns the variant file-content
Since mkDir() and mkFile() returns the object, we can do fancy stuff like chaining make operands together:
mFileSystem.mkDir('first') .mkDir('second') .mkFile('text.txt',null);
But what about speed I hear you say? Well I had to re-code this twice, because like my friend Eric Grange pointed out the other day – JSON.Stringify() is extremely costly in terms of CPU and time. Which means that if every file object supports ISerializable it would take ages before the procedure returns (and then the browser drops the call).
So what I do now is that – when you call SaveTo() to store the full content of the filesystem, it generates a multi-layered array of records. It then calls JSON.Stringify and Deserialize the whole array in a single pass, which is blistering fast.
Note: Localstorage has a limit of some 15 megabytes or so (or was that 10?) so dont expect much. But if you want to store some data, perhaps a document or preferences, then qtx.storage.filesystem is exactly what you need.
Let’s see what happens when we generate 1000 files with a short string as the content. We use TW3LocalStorage as the target medium. Here is a snapshot from Webkit that verifies that it’s been properly stored:
And here is the code which generates the folders and files (pretty neat stuff!):
w3Button1.OnClick:=Procedure (sender:TObject) var x: Integer; mName: String; mFileSystem: TQTXFileSystem; mStore: TW3LocalStorage; begin mFileSystem:=TQTXFileSystem.Create(NIL); try mFileSystem.mkDir('first') .mkDir('second') .mkFile('text.txt',null); for x:=1 to 1000 do begin mName:="file" + getNewID().toString() + ".txt"; mFileSystem.mkfile(mName,"this is fantastic"); end; mStore:=TW3LocalStorage.Create; try mStore.Open("filesystem"); try mFileSystem.SaveTo("files",mStore); finally mStore.Close; end; finally mStore.free; end; showmessage("Data stored!"); finally mFilesystem.free; end; end;