Re: The most basic File API use case

On Tue, Dec 8, 2009 at 9:03 AM, Robin Berjon <robin@berjon.com> wrote:
> Hi Peter!
>
> On Dec 7, 2009, at 22:51 , Peter O. Ussuri wrote:
>> Fair point - playing with encoding(s) is probably not the right place here. We thus can have just a binary builder and leave text/strings out of the 'building' process altogether. FileWriter can be instructed later to write/save either a blob or a string.
>
> Actually I've changed my mind here :)
>
> If we have a method that can write out a text file, it simply take a string (and then indeed a global encoding to apply to all the file). But for blobs, given that you're writing out binary anyway, it is less important to control the global encoding. In fact there are probably binary formats that can only take US-ASCII in place but that might accept UTF-8 elsewhere. See below for details.
>
>> Thus if "a proposal for binary data in ES" is nowhere near stability (I can't tell), I suggest a simple binaryBuilder/blobBuilder interface is introduced to move things forward.
>
> Agreed. My proposal below doesn't have the full details of what can be done to add some binary, but that can easily be added.
>
>> Regarding "continuous writing": I agree that there are use cases that would benefit a lot from it, so the behavior should be specified and implemented in some way down the road. However, as you point it out yourself, there are some open issues to be clarified/resolved around it. Thus my suggestion would be to design FileWriter in a way that would keep the continuous writing option "on the table", but have a "write-and-done" method specified now, so that vendors can implement it.
>
> Listening to you and Jonas, that's what I've tried to do now.
>
> Here's roughly what I propose:
>
> First we have a FileWriter. It can save to both text (with options for encoding and line endings) and to binary (if given a blob). It is designed to look a lot like FileReader (and thus XHR). That does lead to some amount of extra verbosity, but I think that the alignment is worth it. Hopefully the general idea is clear.
>
>
> [Constructor(DOMString mediaType, DOMString fileName)]
> interface FileWriter {
>    // saving operations
>    void save (DOMString content, optional DOMString encoding, optional DOMString endings);
>    void save (Blob data);
>
>    // abort the save
>    void abort();
>
>    // state codes
>    const unsigned short INITIAL = 0;
>    const unsigned short WRITING = 1;
>    const unsigned short DONE    = 2;
>    readonly attribute unsigned short readyState;
>
>    // error, same as FileReader but with some additions
>    readonly attribute FileError error;
>
>    // event handler attributes
>    attribute Function onloadstart;
>    attribute Function onprogress;
>    attribute Function onload;
>    attribute Function onabort;
>    attribute Function onerror;
>    attribute Function onloadend;
> };
> FileWriter implements EventTarget;
>
>
> Then we have a WritableBlob. I'm not married to the name, I just liked the approach of having a single object which both contains the data and does the manipulation, as opposed to the builder object from which you get the content when you're done. The level of indirection didn't seem necessary, but maybe I missed something. As I said above, we can have more options as in your BlobBuilder to add content into it, and we don't have to use overloading if people don't like it (or if it doesn't scale). If we do stick to overloading I wouldn't be adverse to adding Constructor(Blob blob) and Constructor(octet val).
>
> [Constructor]
> interface WritableBlob : Blob {
>    void put (Blob blob);
>    void put (octet val);
>    void put (DOMString string, optional DOMString encoding);
> };
>
> I've also been wondering if we should add put(Blob... blob), put(octet... val), put(Blob[] blobs), put(octet[] vals), etc. Again, those are trivial changes.
>
> Some examples:
>
> //  1. writing out a text file like the one in my FileWriter draft
> var str = "";
> for (var i = 0; i < 10; i++) str += "I am dahut number " . i . "\n";
> var fw = new FileWriter("text/plain", "ten-dahuts.txt");
> fw.onload = function () { alert("File has been saved!"); }
> fw.onerror = function (err) { alert("Failed to save file: " + err.code); }
> fw.save(str);
>
> //  2. writing out an image -- it's very much the same
> var blob = loadDVDContent("The Blob"); // a blob with some video content
> var fw = new FileWriter("video/ogg", "the-blob.ogg");
> fw.onload = function () { alert("Be afraid!"); }
> fw.onerror = function (err) { alert("Be very afraid!"); }
> fw.save(blob);
>
> //  3. creating a blob from scratch
> var blob = new WritableBlob();
> for (var i = 0; i < 10; i++) blob.put(i); // a very useful binary file
>
> Thoughts? If people like the general design, I'll make a draft of it and send it out for review. We can then tweak the various options — but what I'm most interested in first is getting some consensus around the overall shape of it.

Just making sure I've got the interface clear:

FileWriter doesn't quite correspond to FileReader.
When you want to read, you get a File from somewhere, which is
basically a reference to a path or file from which you can read, much
like the Java file.
You then create a FileReader, and in the readAsText call you hand in
the File, saying "Read this file for me, and return the data in the
completion event".

When you want to write, you get a FileWriter from somewhere; it's both
a reference to a path/file and the mechanism by which one writes.  You
then hand it a Blob or String, and it writes it out for you.

This is not a huge deal by itself; the two don't necessarily have to
match perfectly.  However, thinking about it in the context of the
directory API or other means of getting a file handle, I think we
should split writing and the writable file so that they do.  I'll
follow up more in the directory API thread on DAP.

     Eric

Received on Wednesday, 9 December 2009 22:55:20 UTC