Reading files in JavaScript using the File APIs



Reading files in JavaScript using the File APIs


Introduction

HTML5 finally provides a standard way to interact with local files, via the File APIspecification. As example of its capabilities, the File API could be used to create a thumbnail preview of images as they're being sent to the server, or allow an app to save a file reference while the user is offline. Additionally, you could use client-side logic to verify an upload's mimetype matches its file extension or restrict the size of an upload.

The spec provides several interfaces for accessing files from a 'local' filesystem:

  1. File - an individual file; provides readonly information such as name, file size, mimetype, and a reference to the file handle.
  2. FileList - an array-like sequence of File objects. (Think  or dragging a directory of files from the desktop).
  3. Blob - Allows for slicing a file into byte ranges.

When used in conjunction with the above data structures, the FileReaderinterface can be used to asynchronously read a file through familiar JavaScript event handling. Thus, it is possible to monitor the progress of a read, catch errors, and determine when a load is complete. In many ways the APIs resembleXMLHttpRequest's event model.

Selecting files

The first thing to do is check that your browser fully supports the File API:

// Check for the various File API support.
if (window.File && window.FileReader && window.FileList && window.Blob) {
  // Great success! All the File APIs are supported.
} else {
  alert('The File APIs are not fully supported in this browser.');
}

Of course, if your app will only use a few of these APIs, modify this snippet accordingly.

Using form input for selecting

The most straightforward way to load a file is to use a standard  element. JavaScript returns the list of selected File objects as aFileList. Here's an example that uses the 'multiple' attribute to allow selecting several files at once:

 type="file" id="files" name="files[]" multiple />
 id="list">

Example: Using form input for selecting. Try it!

Using drag and drop for selecting

Another technique for loading files is native drag and drop from the desktop to the browser. We can modify the previous example slightly to include drag and drop support.

 id="drop_zone">Drop files here
id="list">

Example: Using drag and drop for selecting. Try it!

Drop files here

Note: Some browsers treat  elements as native drop targets. Try dragging files onto the input field in the previous example.

Reading files

Now comes the fun part!

After you've obtained a File reference, instantiate a FileReader object to read its contents into memory. When the load finishes, the reader's onload event is fired and its result attribute can be used to access the file data.

FileReader includes four options for reading a file, asynchronously:

  • FileReader.readAsBinaryString(Blob|File) - The resultproperty will contain the file/blob's data as a binary string. Every byte is represented by an integer in the range [0..255].
  • FileReader.readAsText(Blob|File, opt_encoding) - Theresult property will contain the file/blob's data as a text string. By default the string is decoded as 'UTF-8'. Use the optional encoding parameter can specify a different format.
  • FileReader.readAsDataURL(Blob|File) - The result property will contain the file/blob's data encoded as a data URL.
  • FileReader.readAsArrayBuffer(Blob|File) - The resultproperty will contain the file/blob's data as an ArrayBuffer object.

Once one of these read methods is called on your FileReader object, theonloadstartonprogressonloadonabortonerror, and onloadend can be used to track its progress.

The example below filters out images from the user's selection, callsreader.readAsDataURL() on the file, and renders a thumbnail by setting the 'src' attribute to a data URL.



 type="file" id="files" name="files[]" multiple />
 id="list">

Example: Reading files. Try it!

Try this example with a directory of images!


Slicing a file

In some cases reading the entire file into memory isn't the best option. For example, say you wanted to write an async file uploader. One possible way to speed up the upload would be to read and send the file in separate byte range chunks. The server component would then be responsible for reconstructing the file content in the correct order.

Lucky for us, the File interface supports a slice method to support this use case. The method takes a starting byte as its first argument, ending byte as its second, and an option content type string as a third.

var blob = file.slice(startingByte, endindByte);
reader.readAsBinaryString(blob);

The following example demonstrates reading chunks of a file. Something worth noting is that it uses the onloadend and checks the evt.target.readyStateinstead of using the onload event.



 type="file" id="files" name="file" /> Read bytes: 
 class="readBytesButtons">
   data-startbyte="0" data-endbyte="4">1-5
   data-startbyte="5" data-endbyte="14">6-15
   data-startbyte="6" data-endbyte="7">7-8
  

 id="byte_range">
id="byte_content">

Example: Slicing a file. Try it!

 Read bytes:  1-5  6-15 7-8  entire file

Monitoring the progress of a read

One of the nice things that we get for free when using async event handling is the ability to monitor the progress of the file read; useful for large files, catching errors, and figuring out when a read is complete.

The onloadstart and onprogress events can be used to monitor the progress of a read.

The example below demonstrates displaying a progress bar to monitor the status of a read. To see the progress indicator in action, try a large file or one from a remote drive.



 type="file" id="files" name="file" />
 onclick="abortRead();">Cancel read
 id="progress_bar"> class="percent">0%

Example: Monitoring the progress of a read. Try it!

  Cancel read
0%

Tip: To really see this progress indicator in action, try a large file or a resource on a remote drive.

References

  • File API specification
  • FileReader interface specification
  • Blob interface specification
  • FileError interface specification
  • ProgressEvent specification




你可能感兴趣的:(<=即时总结=>,平台-Html5)