October 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Using the File API Outside the Sandbox in Chrome Packaged Apps

  • April 26, 2013
  • By David Talbot
  • Send Email »
  • More Articles »

Reading and Writing Files Outside the Sandbox

Chrome installed applications have the ability to store and retrieve files locally from disk. This includes the ability to allow the user to choose a file outside of the sandbox that your application can then read and write from.

Where the Wild Files Are

Temporary local file system storage is shared and low security but persistent local file system storage is sandboxed per application. Using the standard HTML5 file access API, you can create files and read them back later but you don't have direct access to modify just any file on disk. If you get the reference to the file handle you'll see your file is in "C:\fakePath".

Using the chrome fileSystem API you can pop a dialog that allows the user to choose any file anywhere on the disk that the user has access, modify the file, then let the user save the file anywhere on the file system that they have access. Using the HTML 5 standard file API there is no option that will allow you to pop a file save dialog anywhere on the operating system.

Getting Started

To enable the newer Chrome file APIs, you will need to set the "minimum_chrome_version" property to 23 and include the fileSystem write permission shown in the manifest.json file below.

{
  "name": "FileIO",
  "version": "1.0",
  "manifest_version": 2,
  "minimum_chrome_version": "23",
  "app": {
  "background": {
  "scripts": ["background.js"]
  }
  },
  "icons": {
  "128": "Test.png"
  },
  "permissions": [
  {"fileSystem": ["write"]}
  ]
 }

Reading the File

All of the JavasSript file APIs are asynchronous by nature including many callback functions. This can be a little awkward at first for anyone who comes from a strongly server side background steeped in FileStream and buffered reads. It can also lead to some pretty complex code. In return for all of this complexity, you get asynchronous file access that won't cause the user interface to lock up while you are reading or writing files.

The chrome.fileSystem.chooseEntry API opens a file chooser dialog, which is filtered based on the accept types you list. The accepts property takes an array of objects as a parameter. Each of these objects can define extensions or mimeTypes that you want the user to choose from. The second parameter is the callback that will be called when the user is done choosing a file.

When the user does choose a file, the parameter passed to your callback is a FileEntry object. This object contains meta data about the file and includes a function to get a reference to the file itself. If the user does not select a file, the fileEntry passed to your callback is null.

To read the file selected, call the "file" method and use an HTML5 standard FileReader object to read the contents of the file.

chrome.fileSystem.chooseEntry(
  {
  type: 'openFile', accepts:[{
  extensions: ['html']
  }] 
  }, 
  function(fileEntry) {
  if (!fileEntry) {
 $("#OuptutText").html("User did not choose a file");
  return;
  }
  fileEntry.file(function(file) {
  var reader = new FileReader();
  reader.onload = function(e) {
  document.getElementById("HTMLFile").value = e.target.result;
  };
  reader.readAsText(file);
  });
});

Writing the File

Writing the file to disk is almost identical to reading it from disk. Call chrome.fileSystem.chooseEntry with the type of 'saveFile'. The callback function returns a FileEntry object as before, which you can then call createWriter on in order to get a writable file handle that you can then write to using the HTML5 standard file API.

When writing a file, you can also optionally set the suggestedName property to set the default name of the file to be saved. The user can of course rename or choose a different file.
The only thing to note here is that if you previously have been using WebkitBlobBuilder to build your file, you don't need to any more. Chrome now supports the HTML5 Blob object without needing to use the non-standard Webkit extensions.

chrome.fileSystem.chooseEntry({type: 'saveFile', 
 suggestedName: 'myfile.html'}, 
  function(writableFileEntry) {
  writableFileEntry.createWriter(function(writer) {
  writer.onwriteend = function(e) {
  $("#OuptutText").html("Save complete!");
  };
  writer.write(new Blob([document.getElementById("HTMLFile").value], {type: 'text/plain'})); 
  }, errorHandler);
 });

Saving without Prompting for Filename

In a typical application, the user has two options for saving. They can either click save to save the file overwriting the file they opened or they can choose "Save As" to save the file as a separate file from the one they opened. The previous example is perfect if you want to provide the user with the "Save As" experience every time. If you want to provide them the "Save overwriting the file I opened" experience, you will need to open the file using "openWritableFile" as the type.

 chrome.fileSystem.chooseEntry(
  {
  type: ' openWritableFile', accepts:[{
  extensions: ['html']
  }] 
  }, 
  function(fileEntry) {
 //... You can call both fileEntry.file() to read or
 //... fileEntry.createWriter() to write
  }

About the Author:

David Talbot has over 14 years of experience in the software industry and specializes in building rich UI web applications. He is also the author of Applied ADO.NET and numerous articles on technology. He can be reached at mailto:mdavid@legendarycode.com


Tags: API, Chrome, sandbox, Chrome Packaged Apps




Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel