WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
250495
Data written via FileSystemSyncAccessHandle disappears after creating new FileSystemFileHandle
https://bugs.webkit.org/show_bug.cgi?id=250495
Summary
Data written via FileSystemSyncAccessHandle disappears after creating new Fil...
Alex Titarenko
Reported
2023-01-11 19:57:04 PST
With many attempts, I could not find a way to persist written data to FileSystemSyncAccessHandle. The example from
https://webkit.org/blog/12257/the-file-system-access-api-with-origin-private-file-system/
article works only if you try to getFile/read data from the same instance of FileSystemFileHandle, when you get a new instance of FileHandle all data disappears. This can be easily reproduced with a slight modification to the existing LayoutTest at:
https://github.com/WebKit/WebKit/blob/3729059e6a040c8c168679975c9d04dab48e5a4d/LayoutTests/storage/filesystemaccess/resources/file-handle-getfile.js#L44
If before `fileObject = await fileHandle.getFile();` line you place `fileHandle = await rootHandle.getFileHandle("file-handle-getfile.txt", { "create" : false });` you will not get any actual data in return, even if you add accessHandle.flush() call before accessHandle.close(); This works perfectly fine in Chrome but not in WebKit. FileSystemSyncAccessHandle is the only available way to write data in WebKit but it's not working because it does not persist data.
Attachments
Add attachment
proposed patch, testcase, etc.
Alex Titarenko
Comment 1
2023-01-11 20:22:13 PST
More clear information on how to reproduce: In file:
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/filesystemaccess/resources/file-handle-getfile.js
replace test function with: ``` async function test() { try { var rootHandle = await navigator.storage.getDirectory(); // Create a new file for this test. await rootHandle.removeEntry("file-handle-getfile.txt").then(() => { }, () => { }); fileHandle = await rootHandle.getFileHandle("file-handle-getfile.txt", { "create" : true }); fileContent = ""; // Write file content in worker. if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { console.log('hello from WebWorker') accessHandle = await fileHandle.createSyncAccessHandle(); const encoder = new TextEncoder(); fileContent = "This is a test."; writeBuffer = encoder.encode(fileContent); writeSize = accessHandle.write(writeBuffer, { "at" : 0 }); shouldBe("writeSize", "writeBuffer.byteLength"); accessHandle.flush(); // This is a new line accessHandle.close(); } fileHandle = await rootHandle.getFileHandle("file-handle-getfile.txt"); // This is a new line fileObject = await fileHandle.getFile(); readText = await read(fileObject); shouldBe("readText", "fileContent"); finishTest(); } catch (error) { finishTest(error.toString()); } } ``` Then run LayoutTest:
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/filesystemaccess/file-handle-getfile-worker.html
Sihui Liu
Comment 2
2023-01-12 11:26:36 PST
Comment hidden (obsolete)
(In reply to Alex Titarenko from
comment #1
)
> More clear information on how to reproduce: > > In file: >
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/
> filesystemaccess/resources/file-handle-getfile.js > > replace test function with: > > ``` > async function test() > { > try { > var rootHandle = await navigator.storage.getDirectory(); > // Create a new file for this test. > await rootHandle.removeEntry("file-handle-getfile.txt").then(() => { > }, () => { }); > fileHandle = await > rootHandle.getFileHandle("file-handle-getfile.txt", { "create" : true }); > fileContent = ""; > > // Write file content in worker. > if (typeof WorkerGlobalScope !== 'undefined' && self instanceof > WorkerGlobalScope) { > console.log('hello from WebWorker') > accessHandle = await fileHandle.createSyncAccessHandle(); > const encoder = new TextEncoder(); > fileContent = "This is a test."; > writeBuffer = encoder.encode(fileContent); > writeSize = accessHandle.write(writeBuffer, { "at" : 0 }); > shouldBe("writeSize", "writeBuffer.byteLength"); > accessHandle.flush(); // This is a new line > accessHandle.close(); > } > > fileHandle = await > rootHandle.getFileHandle("file-handle-getfile.txt"); // This is a new line > fileObject = await fileHandle.getFile(); > readText = await read(fileObject); > shouldBe("readText", "fileContent"); > > finishTest(); > } catch (error) { > finishTest(error.toString()); > } > } > ``` > > Then run LayoutTest: >
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/
> filesystemaccess/file-handle-getfile-worker.html
Sihui Liu
Comment 3
2023-01-12 11:28:12 PST
(In reply to Alex Titarenko from
comment #1
)
> More clear information on how to reproduce: > > In file: >
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/
> filesystemaccess/resources/file-handle-getfile.js > > replace test function with: > > ``` > async function test() > { > try { > var rootHandle = await navigator.storage.getDirectory(); > // Create a new file for this test. > await rootHandle.removeEntry("file-handle-getfile.txt").then(() => { > }, () => { }); > fileHandle = await > rootHandle.getFileHandle("file-handle-getfile.txt", { "create" : true }); > fileContent = ""; > > // Write file content in worker. > if (typeof WorkerGlobalScope !== 'undefined' && self instanceof > WorkerGlobalScope) { > console.log('hello from WebWorker') > accessHandle = await fileHandle.createSyncAccessHandle(); > const encoder = new TextEncoder(); > fileContent = "This is a test."; > writeBuffer = encoder.encode(fileContent); > writeSize = accessHandle.write(writeBuffer, { "at" : 0 }); > shouldBe("writeSize", "writeBuffer.byteLength"); > accessHandle.flush(); // This is a new line > accessHandle.close(); > } > > fileHandle = await > rootHandle.getFileHandle("file-handle-getfile.txt"); // This is a new line > fileObject = await fileHandle.getFile(); > readText = await read(fileObject); > shouldBe("readText", "fileContent"); > > finishTest(); > } catch (error) { > finishTest(error.toString()); > } > } > ``` > > Then run LayoutTest: >
https://github.com/WebKit/WebKit/blob/main/LayoutTests/storage/
> filesystemaccess/file-handle-getfile-worker.html
Thanks for the report. I think it's caused by file being truncated unexpectedly on FileSystemHandle creation. Will make a fix.
Radar WebKit Bug Importer
Comment 4
2023-01-12 11:29:25 PST
<
rdar://problem/104187327
>
Sihui Liu
Comment 5
2023-01-12 11:32:28 PST
Pull request:
https://github.com/WebKit/WebKit/pull/8586
EWS
Comment 6
2023-01-13 09:29:48 PST
Committed
258876@main
(60a6090b4106): <
https://commits.webkit.org/258876@main
> Reviewed commits have been landed. Closing PR #8586 and removing active labels.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug