Scriptable IO
So one thing that is hard to do in Mozilla is read and write to files. This invoves a lot of creating of XPCOM components, initializing them and wrapping them in various other streams components. Or, you could use a library like jslib or similar. But it doesn’t have to be that way. What if an easier method was built-in:
// write a string to the file stuff.txt from the Home directory.
var file = IO.newFile("Home", "stuff.txt");
var stream = IO.newOutputStream(file, "text");
stream.writeString("This is a file\n");
stream.close();
And what if a similar technique could be used for reading and writing from files, sockets or other streams? What if this was reality?
See Scriptable IO for more details. Comments very welcome, especially on the API.
May 9th, 2007 at 6:32 pm
Microsoft has been doing this for years now, you may want to take a peak at their Object Model for a few pointers.
It works extremely well, and is very simple to code upon.
Just search for “Scripting.FileSystemObject”
And/or I’ll be more then happy to assist.
Your current syntax looks as awfully complex as using the xpcom instances already are!!
Another model to look into is the “ADODB.Stream” it is far less work then doing the Input|Output Stream hoops you must jump through in xpcom.
May 9th, 2007 at 7:29 pm
I haven’t read most of the API yet, but is the plan to expose this in all scripting contexts? Or only chrome ones? Or something else?
May 9th, 2007 at 9:16 pm
Coming from the xbase world where everything was a simple function, I propose two functions:
- IO.StringToFile(fileName,anyString,flags)
and
- anyText = IO.FileToString(fileName)
Life was easier back then
May 9th, 2007 at 11:47 pm
” For instance, using the location key ‘Desk’ will retrieve files in the desktop folder, and the location key ‘TmpD’ will retrieve files in the system’s temporary directory.”
eww. can you please use non abbreviated names such as “Desktop” and “Temp”.
May 9th, 2007 at 11:50 pm
If this were reality I wouldn’t have to install jslib for a lot of projects. That would be nice indeed…not because jslib is bad, I couldn’t do without it, just because its one more thing that has to be managed. Does this overlap with the work the FUEL project is doing? Seems like there is a lot of thought going into making life easier for development in the javascript/chome realm, lately. Music to my ears.
If indeed the success of Firefox is due, in large part, to the extension developer community that it has fostered, this type of work is worth its weight in gold.
The extensions I build are used mostly internally at our company and always have some IO component to them. These types of features would be a great boon to a lot of developers like me who probably never show up on the public radar. With all the talk lately about the importance of the XULRunner platform, I can’t help but think a lot of the mileage could be had from just integrating the features jslib enshrouds into the Mozilla code base. Forge ahead my good man, forge ahead!
May 10th, 2007 at 2:46 am
API comments:
nsIFile newFile, nsIFile newFileWithPath: shouldn’t these be nsILocalFile?
nsISupports newInputStream(in nsIVariant base, in AString type);
First, you really should not mix four different input types in the first argument. You’d be better off declaring a different method for each input type.
Second, string types for the second argument? That’s like magic numbers - and evil for the exact same reason. I recommend using constants on the nsIScriptableIO interface, and requiring people pass in one of those named constants. Ditto for the modes of nsIOutputStream (though you could use single-bit flags for that).
I may comment more later.
May 10th, 2007 at 3:10 am
I’m agree with George : IO.StringToFile and IO.FileToString are simplier. I love it.
@Neil : your API is simplier than the actual API, it can be useful for a complex use, but it is still too complex for most of purpose (why a “normal” developer has to manage a “stream” ??).
May 10th, 2007 at 3:30 am
Seems to me that this is something that could (should?) fit into FUEL so we have just one neat library for JS users. http://wiki.mozilla.org/FUEL
May 10th, 2007 at 4:45 am
I think you might also take a look how its done in PHP. I think it’s very simple and easy to use [http://www.php.net/manual/en/function.fopen.php]. I specially like the fgetscsv function, which lets you get a line from the file pointer and parse it for CSV fields.
May 10th, 2007 at 8:23 am
Lucky: I don’t understand. The example above would require 10-15 lines of code using the existing api instead of 4. Also, the “Scripting.FileSystemObject” object is very similar to what I’m proposing.
Boris: chrome only, or privileged only, or something
George: I can add a readAll function.
Mossop: it is one and the same. See bug 380168
Alex: they have classinfo so will be flattened for JS use. This API isn’t intended to be used from native code. “First, you really should not mix four different input types in the first argument.” No, this API is meant to be easier to use. Having multiple functions means you need to think about which one to use, rather than having a machine just do it for you. Also, strings are easier to type than constants.
May 10th, 2007 at 8:32 am
Is this really necessary? You’re still creating the same classes, just hiding the Components calls.
Most of the simple code I need for file IO is listed at MDC under code snippets. Creating a quick file object by cutting and pasting takes all of about 5 minutes. I can avoid using JSLib, and in the end I get a File() object which does exactly what I want. File.openWithFilePicker(). File.read(). File.readLines(). File.write(), File.save() etc. etc. etc.
All the abstraction just seems silly. This isn’t that big of a problem. Its not like trying to dig through TB’s mail database or anything. Its well documented and easy to do.
May 10th, 2007 at 9:07 am
DigDug: yes, because if you have to resort to copying code from a sample, it almost always means that what you’re trying to do is too hard. Also, if you’re referring to http://developer.mozilla.org/en/docs/Code_snippets:File_I/O then no, that isn’t any near what I would call ‘well documented’. Documentation is about teaching developers how to use code and how and why it functions, so that they don’t blindly copy code from some sample without understanding why it isn’t the right code for what they are trying to do, which leads to buggy and poorly written code.
May 10th, 2007 at 1:23 pm
I’d prefer the idea posted by George above - there’s functions like it in PHP5, called “file_get_contents” and file_put_contents”, which do exactly what you’d expect. Much nicer than having to remember to do the whole open/do stuff/close dance each time.
May 10th, 2007 at 6:54 pm
Enn: I didn’t see much that resembled the MS IO, but I’ll look closer…
The functions need to automagically handle whatever arguments is sent to it!!
eg: if i say
var f = new io.file(”my.txt”);
then it should negotiate that value, even if it falls under chrome://..
and or, i could just as easily:..
var f = new io.file(”chrome://someext/global/you/get.the.idea”);
also, directory recursion/ testing should be simple..
var dirArray = io.folders(”some/path/”);
var files = io.files(”some/path/”, /\.xml/);
returning an array of the file objects
[nsIFile, nsIFile, nsIFile, …]
also, a built-in browse is nice..
var f = io.browse(”Select a file”, io.BROWSEFILE);
be more then happy to share some stuff i’ve done along these lines.
April 19th, 2008 at 10:02 pm
This would be cool if they actually did it. I have my own collection of functions the I carry around to handle all my file.io stuff since I hate having to write it all the time. Just nice and simple fileGetContents(nsiFile) filePutContents(nsiFile,data) getUrlContents(aURL) and askForFile()
It would be good if Firefox/Mozilla came with it by default.