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.
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
(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
(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.
<rdar://problem/104187327>
Pull request: https://github.com/WebKit/WebKit/pull/8586
Committed 258876@main (60a6090b4106): <https://commits.webkit.org/258876@main> Reviewed commits have been landed. Closing PR #8586 and removing active labels.