Re: Request for feedback: Filesystem API

On Fri, Aug 16, 2013 at 11:50 AM, Jonas Sicking <jonas@sicking.cc> wrote:
>> Variation: what happens if I do:
>>
>> var fileHandle;
>> navigator.getFilesystem().then(function(root) {
>>     return root.openWrite("highscores"); //highscores is 100-bytes long
>>  }).then(function(handle) {
>>     fileHandle = handle;
>>     return fileHandle.read(1000); //offset is set to 1000?
>
> This read would result in an error.
>
>>  }).then(function(buffer) {
>>     result=calculateSomething(buffer);
>>     fileHandle.write(result); //append result at offset 100 or 1000?
>
> Which means that this code isn't called at all. The first argument to
> .then() is the success callback which is only called if the promise
> successfully returned a value.

Sorry, I misread the code here.

I think reading past the end of the file should not be an error,
though that's something that I'd love to get feedback on.

If that's the case then the initial read will be successful, but would
only return an ArrayBuffer which is 100 bytes long.

The call to .read() will synchronously set .offset to 1000.

That means that when .write() is called, .offset is still 1000 and so
we will write to offset 1000 by filling the area 100-1000 with
0-bytes, and then write 'result' after that.

If you want to make sure to always append, do something like

var fileHandle;
navigator.getFilesystem().then
(function(root) {
    return root.openWrite("highscores"); //highscores is 100-bytes long
 }).then(function(handle) {
    fileHandle = handle;
    return fileHandle.read(1000); //offset is set to 1000
 }).then(function(buffer) {
    result=calculateSomething(buffer);
    fileHandle.offset = null; // append
    fileHandle.write(result);
 });

If you want to make sure to always write the result after the read
buffer, do something like:

var fileHandle;
navigator.getFilesystem().then
(function(root) {
    return root.openWrite("highscores"); //highscores is 100-bytes long
 }).then(function(handle) {
    fileHandle = handle;
    return fileHandle.read(1000); //offset is set to 1000
 }).then(function(buffer) {
    result=calculateSomething(buffer);
    fileHandle.offset = buffer.byteLength;
    fileHandle.write(result);
 });

The .offset property is simply syntax to aid with consecutive
reads/writes. It's not actually affected by any IO operations. This
enables doing things like

navigator.getFilesystem().then
(function(root) {
    return root.openWrite("highscores");
 }).then(function(handle) {
    return Promise.all(handle.read(1000), handle.read(5), handle.read(100));
 }).then(function(results) {
    // results is an array with 3 ArrayBuffers
 });

I.e. you don't need to wait for the previous IO operation to finish
before scheduling the next one. In fact, there are performance
benefits to not waiting.

/ Jonas

Received on Saturday, 17 August 2013 11:34:18 UTC