{"id":188709,"date":"2021-02-25T16:00:56","date_gmt":"2021-02-25T13:00:56","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/"},"modified":"2021-02-25T16:00:56","modified_gmt":"2021-02-25T13:00:56","slug":"web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/","title":{"rendered":"#Web Apps Can Interact With Your Filesystem Now \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a41fce72ab41\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a41fce72ab41\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Overview\" >Overview<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Reading_a_File\" >Reading a File<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Writing_to_a_File\" >Writing to a File<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Directories\" >Directories<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Permissions\" >Permissions<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/web-apps-can-interact-with-your-filesystem-now-cloudsavvy-it\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#Web <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">App<\/a>s Can Interact With Your Filesystem Now \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9853\" src=\"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/47dc0c601681e250ec22cb9e6e2eb99d\/p\/uploads\/2021\/02\/f45eb4fc.jpg\" alt=\"Photo of Google Chrome on a smartphone\" width=\"1920\" height=\"1281\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>The File System Access API is a new browser feature that lets websites and apps directly interact with your device\u2019s filesystem. There is now <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/caniuse.com\/native-filesystem-api\">partial support<\/a> for the API in recent Chrome and Opera versions.<\/p>\n<p>What\u2019s now the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/WICG\/file-system-access\">File System Access API<\/a> used to be known as the Native File System API. It\u2019s had a long development involving several rounds of iteration to address security concerns. The feature was turned on in the stable release <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.chrome.com\/blog\/new-in-chrome-86\">of Chrome 86<\/a>.<\/p>\n<h2 id=\"overview\"><span class=\"ez-toc-section\" id=\"Overview\"><\/span>Overview<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>File support on the web has historically been limited to selecting a file from your device using <code>&lt;input type=\"file\"&gt;<\/code>. It\u2019s impossible to write directly to the user\u2019s filesystem using previous APIs. You have to use download links if you need to provide a file to the user.<\/p>\n<p>The File System Access API provides a way for websites to attain read-write access to your device\u2019s filesystem. This makes it possible to create new classes of complex web apps that interact with your files. Web-based text editors, photo libraries and <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/social-mediaa\/\" data-internallinksmanager029f6b8e52c=\"1\" title=\"Social Media\" target=\"_blank\" rel=\"noopener\">media<\/a> players could all load content stored locally on your device.<\/p>\n<p>Using the API, you can enumerate the contents of directories, read data from files and write back to new and existing files stored on the user\u2019s device. Access is provided via the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileSystemFileHandle\"><code>FileSystemFileHandle<\/code><\/a> and <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileSystemDirectoryHandle\"><code>FileSystemDirectoryHandle<\/code><\/a> handle objects, which represent files on the user\u2019s system.<\/p>\n<p>The File System Access API can only be used from pages loaded over HTTPS. It\u2019s gated behind permissions which the user must explicitly consent to. The user will be prompted to provide consent each time you use the API. This uses the same system as permission requests for other web features, such as notifications and camera access.<\/p>\n<p>Like most modern JavaScript APIs, File System Access is asynchronous. Calls to its API surface return <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Promise\">Promises<\/a>. The cleanest way to consume it is via the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/async_function\"><code>async<\/code>\/<code>await<\/code><\/a> syntax of ES7, which is what we\u2019ll use in the following examples.<\/p>\n<h2 id=\"reading-a-file\"><span class=\"ez-toc-section\" id=\"Reading_a_File\"><\/span>Reading a File<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>To read a file, you open a file picker using the <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/showOpenFilePicker\"><code>window.showOpenFilePicker()<\/code><\/a> function. There\u2019s no need to use the HTML <code>&lt;input type=\"file\"&gt;<\/code> element.<\/p>\n<p>The user\u2019s operating system will render a native file picker. Once the user selects a file, the returned Promise will resolve with an array of <code>FileSystemFileHandle<\/code> objects.<\/p>\n<p>To get the contents of the file, call the <code>getFile()<\/code> method of the file handle. This returns a <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/File\"><code>File<\/code> object<\/a>, which is what you get when working with an HTML filepicker. Once you have the <code>File<\/code>, you can use its blob methods such as <code>text()<\/code> and <code>stream()<\/code> to read its data.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> <span class=\"br0\">[<\/span>fileHandle<span class=\"br0\">]<\/span> <span class=\"sy0\">=<\/span> await window.<span class=\"me1\">showOpenFilePicker<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">const<\/span> file <span class=\"sy0\">=<\/span> await file.<span class=\"me1\">getFile<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">const<\/span> fileData <span class=\"sy0\">=<\/span> await file.<span class=\"me1\">text<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nconsole.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span>fileData<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><code>window.showOpenFilePicker()<\/code> accepts an options object as its sole parameter. You can allow the user to select multiple files by setting the <code>multiple<\/code> option. To restrict the user to specific file types, pass the <code>types<\/code> option with an array of objects describing the allowed types. Each type object should contain <code>description<\/code> and <code>accept<\/code> properties which determine the type\u2019s file picker label and permissible MIME types respectively.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> files <span class=\"sy0\">=<\/span> await window.<span class=\"me1\">showOpenFilePicker<\/span><span class=\"br0\">(<\/span><span class=\"br0\">{<\/span>\n    multiple<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"sy0\">,<\/span>\n    types<span class=\"sy0\">:<\/span> <span class=\"br0\">[<\/span>\n        <span class=\"br0\">{<\/span>\n            description<span class=\"sy0\">:<\/span> <span class=\"st0\">\"Image Files\"<\/span><span class=\"sy0\">,<\/span>\n            accept<span class=\"sy0\">:<\/span> <span class=\"br0\">[<\/span><span class=\"st0\">\"image\/jpeg\"<\/span><span class=\"sy0\">,<\/span> <span class=\"st0\">\"image\/png\"<\/span><span class=\"br0\">]<\/span>\n        <span class=\"br0\">}<\/span>\n    <span class=\"br0\">]<\/span>\n<span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"kw1\">for<\/span> await <span class=\"br0\">(<\/span>file of files<span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\n    <span class=\"kw1\">const<\/span> fileData <span class=\"sy0\">=<\/span> await file.<span class=\"me1\">getFile<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n    console.<span class=\"me1\">log<\/span><span class=\"br0\">(<\/span>fileData<span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"br0\">}<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>An \u201call files\u201d option is usually shown as a permissible file type, even when the <code>types<\/code> option is set. You can disable the all files override by setting the <code>excludeAcceptAllOption<\/code> option.<\/p>\n<h2 id=\"writing-to-a-file\"><span class=\"ez-toc-section\" id=\"Writing_to_a_File\"><\/span>Writing to a File<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Once you have a file handle, you can also write to it! There\u2019s another abstraction layer to contend with as you must first acquire a <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/FileSystemWritableFileStream\"><code>FileSystemWritableFileStream<\/code><\/a>. This stream represents the file and allows you to keep writes in-memory until they\u2019re persisted to the disk.<\/p>\n<p>Here\u2019s how to replace the contents of a file handle obtained from <code>showOpenFilePicker()<\/code>:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"co1\">\/\/ User selects a file<\/span>\n<span class=\"kw1\">const<\/span> fileHandle <span class=\"sy0\">=<\/span> await window.<span class=\"me1\">showOpenFilePicker<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Get a `FileSystemWritableFileStream` we can write to<\/span>\n<span class=\"kw1\">const<\/span> writableFileStream <span class=\"sy0\">=<\/span> await fileHandle.<span class=\"me1\">createWritable<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Write new file contents into the stream<\/span>\nawait writableFileStream.<span class=\"me1\">write<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Hello World\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n\u00a0\n<span class=\"co1\">\/\/ Close the writable stream - its content is now persisted to the file on disk<\/span>\nawait writableFileStream.<span class=\"me1\">close<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Calling <code>write()<\/code> on a writable stream will insert text at the current cursor position in the stream. To change the position of the cursor, call the <code>seek()<\/code> method passing the new cursor position. A third method on writable streams is <code>truncate()<\/code>, which resizes the file down to a maximum size in bytes which you must specify.<\/p>\n<p>Sometimes you\u2019ll need to write to a new file. You can do this by asking the user to pick a new location for the file using <code>window.showSaveFilePicker()<\/code>. This works similarly to <code>window.showOpenFilePicker()<\/code> \u2013 it returns a <code>FileHandle<\/code> which you\u2019ll then be able to call <code>createWritable()<\/code> on to get a writable stream.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> fileHandle <span class=\"sy0\">=<\/span> await window.<span class=\"me1\">showSaveFilePicker<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">const<\/span> writable <span class=\"sy0\">=<\/span> await fileHandle.<span class=\"me1\">createWritable<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nawait writable.<span class=\"me1\">write<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Hello World\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nawait writable.<span class=\"me1\">close<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>You can use the <code>excludeAcceptAllOption<\/code> and <code>types<\/code> options with <code>window.showSaveFilePicker()<\/code>. They work identically to their <code>showOpenFilePicker()<\/code> counterparts.<\/p>\n<h2 id=\"directories\"><span class=\"ez-toc-section\" id=\"Directories\"><\/span>Directories<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The File System Access API also exposes directories. The user can be prompted to select a directory using <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Window\/showDirectoryPicker\"><code>window.showDirectoryPicker()<\/code><\/a>. This function accepts no parameters. It returns a promise which will resolve with a <code>FileSystemDirectoryHandle<\/code> representing the directory.<\/p>\n<p>You can enumerate the contents of the directory by iterating over its <code>values()<\/code>. The values will be either file or directory handle instances.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> directoryHandle <span class=\"sy0\">=<\/span> window.<span class=\"me1\">showDirectoryPicker<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\n<span class=\"kw1\">for<\/span> await <span class=\"br0\">(<\/span>let handle of directoryHandle.<span class=\"me1\">values<\/span><span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\n    <span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>handle.<span class=\"me1\">type<\/span> <span class=\"sy0\">===<\/span> <span class=\"st0\">\"file\"<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\n        <span class=\"co1\">\/\/ file<\/span>\n    <span class=\"br0\">}<\/span>\n    <span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>handle.<span class=\"me1\">type<\/span> <span class=\"sy0\">===<\/span> <span class=\"st0\">\"directory\"<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\n        <span class=\"co1\">\/\/ subdirectory<\/span>\n    <span class=\"br0\">}<\/span>\n<span class=\"br0\">}<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>If you know the name of the file or subdirectory you\u2019re looking for, you can use the <code>getFileHandle()<\/code> or <code>getDirectoryHandle()<\/code> methods to retrieve it. These methods both accept an options object which currently has a single property, <code>create<\/code>. Setting this to <code>true<\/code> will cause the requested file or directory to be automatically created within the filesystem if it doesn\u2019t already exist.<\/p>\n<p>You can delete files and folders from a directory using the <code>removeEntry()<\/code> method on a directory handle. This accepts the relative name of the file or subdirectory to delete. When deleting a directory, you may optionally set the <code>recursive<\/code> option to also remove its contents.<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\">await directoryHandle.<span class=\"me1\">removeEntry<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"file.txt\"<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span>\nawait directoryHandle.<span class=\"me1\">removeEntry<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"Subdirectory\"<\/span><span class=\"sy0\">,<\/span> <span class=\"br0\">{<\/span>recursive<span class=\"sy0\">:<\/span> <span class=\"kw2\">true<\/span><span class=\"br0\">}<\/span><span class=\"br0\">)<\/span><span class=\"sy0\">;<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2 id=\"permissions\"><span class=\"ez-toc-section\" id=\"Permissions\"><\/span>Permissions<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Permissions for the File System Access API are split into read and write components. Browers will usually show a <em>separate<\/em> permission prompt for both read and write and for each file or directory you access.<\/p>\n<p>Once you\u2019ve acquired permission, you can use the file or directory handle for as long as your site remains open. An exception is if the underlying resource gets changed or modified on disk, in which case the handle is invalidated.<\/p>\n<p>You can check whether you still have permission to use a handle by calling its <code>queryPermission()<\/code> method:<\/p>\n<div class=\"wp-geshi-highlight-wrap5\">\n<div class=\"wp-geshi-highlight-wrap4\">\n<div class=\"wp-geshi-highlight-wrap3\">\n<div class=\"wp-geshi-highlight-wrap2\">\n<div class=\"wp-geshi-highlight-wrap\">\n<div class=\"wp-geshi-highlight\">\n<div class=\"javascript\">\n<pre class=\"de1\"><span class=\"kw1\">const<\/span> mode <span class=\"sy0\">=<\/span> <span class=\"st0\">\"read\"<\/span><span class=\"sy0\">;<\/span>    <span class=\"co1\">\/\/ may also be \"readwrite\"<\/span>\n<span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>await fileHandle.<span class=\"me1\">queryPermission<\/span><span class=\"br0\">(<\/span><span class=\"br0\">{<\/span>mode<span class=\"br0\">}<\/span><span class=\"br0\">)<\/span> <span class=\"sy0\">===<\/span> <span class=\"st0\">\"granted\"<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span>\n    <span class=\"co1\">\/\/ OK<\/span>\n<span class=\"br0\">}<\/span><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>When you need to re-request permission, use the <code>requestPermission()<\/code> method in the same manner.<\/p>\n<p>You should avoid prompting for permission too often or for too many files. This is likely to create a poor user experience due to multiple successive dialogs appearing. Always prompt for permission in response to an explicit user action such as clicking a button.<\/p>\n<p>The API makes no provision for persistent permission grants. Once all tabs for your site <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/web.dev\/file-system-access\">have been closed<\/a>, any granted file permissions will be revoked.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The File System Access API is one of the most exciting browser APIs to have launched in recent months. It has the potential to transform the capabilities of web applications, making them an even more viable alternative to desktop programs.<\/p>\n<p>Whether you\u2019re building a text editor, photo gallery or enterprise line-of-business app, being able to interact with the device\u2019s filesystem gives you new possibilities. Although browser support will be limited to Chrome and Opera for the foreeseable future (Mozilla views the API as <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/mozilla.github.io\/standards-positions\/#native-file-system\">\u201cpotentially very dangerous\u201d<\/a>), File System Access helps evolve the web as an application platform and further reduces the gap between the web and native apps.\n<\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/9852\/web-apps-can-interact-with-your-filesystem-now\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#Web Apps Can Interact With Your Filesystem Now \u2013 CloudSavvy IT&#8221; The File System Access API is a new browser feature that lets websites and apps directly interact with your device\u2019s filesystem. There is now partial support for the API in recent Chrome and Opera versions. What\u2019s now the File System Access API used to&#8230;<\/p>\n","protected":false},"author":1,"featured_media":188710,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/thumbcache\/0\/0\/47dc0c601681e250ec22cb9e6e2eb99d\/p\/uploads\/2021\/02\/f45eb4fc.jpg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-188709","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/188709","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=188709"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/188709\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/188710"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=188709"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=188709"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=188709"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}