File example

SOURCE CODE OF THE EXAMPLE SHOWN IN THE VIDEO

Example on JS Bin

 

  1. <!DOCTYPE html>
  2. <html lang=“en”>
  3. <head>
  4. <meta charset=“utf-8”>
  5. <title>Example of using readAsDataURL</title>
  6. </head>
  7. <body>
  8. <input type=“file” multipleonchange=readImagesAndPreview(this.files);>
  9. <p>
  10. id=“thumbnails”>

  11.    var container = document.getElementById(“thumbnails”);
  12.    function readImagesAndPreview(files) {
  13.       for(var i=0; i files.length; i++) {
  14.          var f = files[i];
  15.          var reader = new FileReader();
  16.          reader.onload = function(e) {
  17.             var img = document.createElement(“img”);
  18.             img.src = e.target.result;
  19.             img.width = 100;
  20.             container.appendChild(img);
  21.          }
  22.          reader.readAsDataURL(f);
  23.      }
  24. }
  25.  
  26. </body>
  27. </html>

 

Getting details about a file: reading metadata

Imagine you have an input field like this:

  1. Select one or more files: <input type=“file” id=“input”/>

This will render as a “select files” or “browse files” button. If you select one file in the file chooser dialog that has popped up, before HTML5 you couldn’t do anything with it in the client-side: no access from JavaScript. With the File API, you can read what we call “file metadata”: name, size, type and last modification date.

Look at the the code below: the file API defines a files property on the DOM node corresponding to the <input type=”file”…/> input field. This property is an array.

In the example below, we get in the selectedFile variable, the metadata related to the first selected file:

  1. var selectedFile = document.getElementById(‘input’).files[0];
  2. // do something with selectedFile.name, selectedFile.size, selectedFile.type
  3. // selectedFile.lastModifiedDate

EXAMPLE 1: READ METADATA OF THE FIRST SELECTED FILE

Here is a complete example on JS Bin that uses the code above to get details about the first selected file. Please try it below on your browser (click on the button and choose one file):

Complete source code:
  1. <!DOCTYPE html>
  2. <html lang=“en”>
  3. <head>
  4. <meta charset=utf-8 />
  5. <title>Reading file metadata</title>
  6.      function displayFirstSelectedFileMetadata() {
  7.         var selectedFile = document.getElementById(‘input’).files[0];
  8.         document.querySelector(“#singleName”).innerHTML = selectedFile.name;
  9.         document.querySelector(“#singleSize”).innerHTML = selectedFile.size + ” bytes”;
  10.         document.querySelector(“#singleType”).innerHTML = selectedFile.type;
  11.         document.querySelector(“#singleDate”).innerHTML selectedFile.lastModifiedDate;
  12. }
  13. </head>
  14. <body>
  15.    Select one or more files: <input type=“file”id=“input”
  16.                                     onchange=displayFirstSelectedFileMetadata();/>
  17. <p>
  18. <ul>
  19.     <li>File name: <span id=“singleName”></span></li>
  20.     <li>File size: <span id=“singleSize”></span></li>
  21.     <li>File type: <span id=“singleType”></span></li>
  22.     <li>File last modification date: <spanid=“singleDate”></span></li>
  23. </ul>
  24. </body>
  25. </html>

EXAMPLE 2: DISPLAY METADATA OF MULTIPLE FILES, USE A FILTER ON THE FILE TYPE

This example is a bit more complicated, as it will display details about all files selected (not only the first) and allows only images to be selected, using the acceptattribute of the input field: <input type=”file” accept=”image/*”…/>.

Example on JS Bin, or try it in your browser: click on the button, and select multiple image files. Notice that in the file selector, files that are not images will be greyed and non selectable.

Source code extract:

  1. Select several images: <input type=“file” accept=“image/*” multipleonchange=“filesProcess(this.files)” name=“selection”/>
  2. <p>
  3. <div id=“result”>…</div>
  4.   function filesProcess(files) {
  5.       var selection =

  6.                        
  7. ;

  8.       for(i=0; ifiles.length ;i++){
  9.           file = files[i];
  10.           selection +=
  11. ;

  12.       }
  13.       selection +=
  14. Name Bytes MIME Type Last modified date
    +file.name+
  15.                     +file.size+
  16.                     +file.type+
  17. +file.lastModifiedDate+

    ;

  18.  
  19.       document.getElementById(“result”).innerHTML = selection;
  20.   }
  21. script>

Explanations:

    • Line1: we used the multiple attribute to allow the selection of multiple files in the file chooser (using shift or control keys). The accept=”image/*”  attribute is a filter that restricts selection to images only. Finally, the onchange listener will call the filesProcess(…) function, passing as parameter the list of selected files for the current element (this.files).
    • Lines 7 and 12: we prepare the HTML code for building a
      with the results.
    • Line 10: this for loop builds all the rows that compose the table, adding HTML code to the selection string variable. At the end of the loop, this variable contains all the HTML code that corresponds to the table of results.
    • Line 18: the table is added to the page. We use the innerHTML attribute of the DOM element corresponding to the
      in order to insert the table as its child in the DOM tree. As such, the table appears on the page dynamically.
    • Blob and File: what are they?

      THE HTML5 FILE API SPECIFICATION INTRODUCES SEVERAL NEW INTERFACES

        • The FileList interface (we already met it: the files property is a FileList),
        • the File interface that is useful for getting details about a file (the filevariable in the for loop of the last example illustrates this) .
        • the Blob interface helps read binary data (only) that is accessed slice by slice (as chunks of data, each one being a “Blob”),
        • and a FileReader interface for reading file content (we will see how to use it in the next section of the course),

      We will not use all of these new interfaces, but let’s explain the difference between Blob and File, as most of the methods exposed by the FileReader interface take indiscriminately a Blob or a File as parameter.

      THE BLOB OBJECT

      An object of type Blob is a structure that represents binary data available as read-only. Most of the time, you will only encounter these objects when you handle files.

      Blob objects have two properties, namely:size and type, which respectively retrieve the size in bytes of the data handled by the Blob and their MIME type.

      There is also a method called slice(), but this is not used in common applications. If you are curious, check the “slicing a file” section of this “Reading files in JavaScript using the File APIs” article.

      THE FILE OBJECT

      File objects are useful for manipulating… files! They inherit the properties and methods of Blob objects, and have two additional properties that are name, for the file name, and lastModifiedDate to get the date of the last modification of the file (in the form of a JavaScript Date object, obviously) .

      Most of the time, we will work with File objects. Blob objects will have real interest when the Filesystem API is widely available (at the moment there is only an experimental version in Chrome), or when you download binary files using Ajax (see example below).

       

      Reading file content

      INTRODUCTION / TYPICAL USE

      Step1: create a FileReader object

      The file API proposes several methods for reading file content, each taken from the FileReader interface. Here is how you create a FileReader object:

      1. var reader = new FileReader();

      Steps 2 & 3: first call a method of the FileReader object for reading the file content, then get the file content in an onload callback

      There are three different methods available for reading a file’s content: readAsText, readAsArrayBuffer for binary data and also as readAsDataURL(the content will be a URL you will use to set the src field of an , , , and also with all existing methods/properties that accept a URL).

      All these methods take as a unique parameter a File object (for example, a file chosen by a user after clicking on a input field). Below, we use, as an example, the readAsText method:

      1. function readFileContent(f) {
      2.    // Executed last: called only when the file content is loaded, e.target.result is
      3.    // The content
      4.    reader.onload = function(e) {
      5.        var content = e.target.result;
      6.        // do something with the file content
      7.        console.log(“File “ + f.name + ” content is: “ + content);
      8.    };
      9.    // Executed first: start reading the file asynchronously, will call the
      10.    // reader.onload callback only when the file is read entirely
      11.    reader.readAsText(f);
      12. }

      The above code shows how a file can be read as text. The function is called, for example by clicking on the button corresponding to a , and by choosing a file.

        • Line 12 is executed first, and asks the Reader object to read the file f as text. As this takes some time, it’s an asynchronous operation that will be executed by the browser in the background. When the file is read, the reader.onloadcallback function is called.
        • Line 4 is executed after line 12, and is called only when the file content is available. This callback takes an event e as a unique parameter, ande.target.result is the file content.

      Practical examples: reading file content as text

      EXAMPLE 1: READ A SINGLE FILE’S CONTENT

      Example at JS Bin, or try it here in your browser

      1. lang=“en”>
      2. charset=“utf-8”>
      3. Example of use of FileReader with a text file
      4. Choose a text file:type=“file” id=“file”
      5.                            onchange=readFileContent(this.files)/>
      6. rows=15 cols=50 id=“fileContent”>
      7. function readFileContent(files) {
      8.      console.log(“In readFileContent”);
      9.      var reader = new FileReader();
      10.     // Executed last: called when the file content is loaded, e.target.result is
      11.     // The content
      12.     reader.onload = function(e) {
      13.         // display content in the textarea with id=”fileContent”
      14.         document.getElementById(“fileContent”).value= e.target.result;
      15.     };
      16.     console.log(“Reading file:” + files[0].name);
      17.     // Executed first: start reading the file asynchronously , will call the onload
      18.     // callback when the file is read
      19.     reader.readAsText(files[0]);
      20. }
      21. </body>
      22. </html>

      This example is the one at the end of the previous page. This time, we show the complete source code above. Remember that the instruction at line 29 is executed first, then when the file is read, the browser will call asynchronously the onloadcallback at line 20.

      EXAMPLE 2: A VARIATION OF THE PREVIOUS ONE, USING MULTIPLE FILES

      Example on JS Bin, or try it below in your browser. This time, please select multiple text files (using shift for multiple selection):

      Source code:
      1. <!DOCTYPE html>
      2. <html lang=“en”>
      3. <head>
      4. <meta charset=“utf-8”>
      5. <title>Example of use of FileReader with a text file</title>
      6. </head>
      7. <body>
      8. <label for=”files”>Choose multiple text files:</label>
      9. <input type=“file” id=“files”
      10.        multipleonchange=readFilesAndDisplayAsText(this.files);/><br/>
      11. <p>
      12. <textarea rows=30 cols=50 id=“filesContent”></textarea>
      13. var filesContent = document.getElementById(“filesContent”);
      14. function readFilesAndDisplayAsText(files) {
      15.      console.log(“dans read files”);
      16.      // Loop through the FileList
      17.      for (var i = 0, f; f = files[i]; i++) {
      18.          var reader = new FileReader();
      19.          // Add an onload listener to the reader
      20.          addOnLoadListener(reader, f.name);
      21.          // start reading, will call the listener later, when the file f is read
      22.          reader.readAsText(f);
      23.      }
      24. }
      25. function addOnLoadListener(reader, name) {
      26.      // Add an onload listener that will be able to print the name of the
      27.      // file…
      28.      reader.onload = function(e) {
      29.          filesContent.value += “###### READING FILE “ + name + ” ######”;
      30.          filesContent.value += e.target.result;
      31.      };
      32. }
      33. </body>
      34. </html>

      Explanations:

      This example is similar to the previous one, except that this time we read multiple files.

      • Line 20: this is the for loop that will iterate on the files object passed as parameter by the onchange listener declaration at line 10
      • Line 25: instead of declaring the onload listener with a reader.onload =… directly in the loop, this time we preferred to write a separate function that will do this. This technique is useful when you want the listener to work with extra variables computed in the loop (in our case, the name of the file).

      ABOUT CHARACTER ENCODING

      Note that you can optionally indicate the encoding of the file you are going to read (default is UTF-8):

      1. reader.readAsText(file, ‘UTF-8’);
      2. reader.readAsText(file, ‘ISO-8859-1’);

      Read file content as binary

      INTRODUCTION

      This method is rarely used, except for loading “raw” binary data. For images you would like to see in your HTML page using the <img src= tag> or for drawing in a canvas, or for audio and video files that you would like to play using the <audio> or <video> elements, it would be preferable to use the readAsDataURL method presented on the next page of the course.

      readAsArrayBuffer is often used for purposes such as reading audio samples that should be loaded in memory and played using the WebAudio API, or for loading textures that you will use with WebGL for 3D animations.

      EXAMPLE 1: READ A LOCAL AUDIO FILE AND PLAY IT WITH THE WEBAUDIO API

      The WebAudio API is useful for reading audio sound samples from memory (no streaming), and has been designed for music application and games. This example shows how a local audio file can be read and played directly in the browser, without the need for a server!

      Example on JS Bin (does not work on IE, as it does not support the WebAudio API). We could not embed it here on the edX platform as it prevents code that uses Ajax to run in its pages.

      Source code extract:

      1. // User selects file. Read it as an ArrayBuffer and pass to the API.
      2. var fileInput = document.querySelector(‘input[type=”file”]’);
      3. fileInput.addEventListener(‘change’, function(e) {
      4.    var reader = new FileReader();
      5.    reader.onload = function(e) {
      6.       initSound(e.target.result);
      7.    };
      8.    // THIS IS THE INTERESTING PART!
      9.    reader.readAsArrayBuffer(this.files[0]);
      10. }, false);

      Explanations:

        • Line 2: we get a pointer to the file selector, the variable fileInput.
        • Line 4: we define a change listener. In this example, we use an anonymous function directly included in the listener definition (the listener is the function(e) {…}).
        • Line 11: when a user chooses a file, the listener will be executed. Line 11 will start the reading of the file content, as a binary file (this is whatreadAsArrayBuffer means: read as binary!). Once the file will be entirely read, the onload callback will be asynchronously called by the browser.
        • Line 7 is the onload callback, executed when the file content is loaded in memory. We pass the file content to the initSound function (see JS Bin example for complete source code) that uses WebAudio to decode it (it may be a compressed file – an mp3 for example – and WebAudio works only with uncompressed audio formats in memory), and to play it.

      Read file content as data URL

      INTRODUCTION TO A DATA URL

      What is a data URL?

      A data URL is a URL that includes type and content at the same time. It is useful, for example,  for inlining images or videos in the HTML of a Web page (on mobile devices, this may speed up the loading of the page by reducing the number of HTTP requests).

      Here is an example of a red square, as a data URL. Copy and paste it in the address bar of your browser, and you should see the red square:

      1. data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==

      This data URL in a browser address bar should look like this:

      data url in adress bar shows a red circle

      If we set the src attribute of an image element <img src=”data:image/png….”> with the data URL of the above screenshot, it will work exactly as if you used a URL that started with http://

      In your browser, you will see a small red circle rendered by this source code:

      1. <imgsrc=“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
      2. AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO
      3. 9TXL0Y4OHwAAAABJRU5ErkJggg==” alt=“Red square” width=50 height=50/>

      And here is the result:

      Red square

      This dataURL format enables file content to be stored in a base64 format (as a string), and adds the MIME type specification of the content. The dataURL can therefore store a file as a URL readable with modern browsers. It is becoming more commonly used on the Web, especially for mobile applications, as inlining images reduces the number of HTTP requests and makes the Web page load faster.

      You will find lots of Web sites and tools for generating dataURL from files, such as the DataURL maker Web site (screenshot below):

      With the above example, you can copy and paste the characters on the left and use them with an <img src=”…”>. Just set the src attribute with it!

      Notice that you can encode any type of file as dataURL, but this format is most frequently used with media files (images, audio, video).

      Example of HTML5 logo embedded in a document without any real image, just a dataURL and CSS

      Try it at JsBin

      EXAMPLE 1: READ IMAGES AS DATA URL AND DISPLAY PREVIEWS IN THE PAGE

      Example 1 is useful for forms that allow the user to select one or more pictures. Before sending the form, you might want to get a preview of the pictures in the HTML page. The reader.readAsDataUrl method is used for that.

      Example on JS Bin or try it below in your browser:

      Source code extract:

      1. <label for=“files”>Choose multiple files:</label>
      2. <input type=“file” id=“files” multiple
      3.         onchange=readFilesAndDisplayPreview(this.files);/><br/>
      4. <p>Preview of selected images:</p>
      5. <output id=“list”></output>
      6.  
      7. <script>
      8.   function readFilesAndDisplayPreview(files) {
      9.     // Loop through the FileList and render image files as thumbnails.
      10.     for (var i = 0, f; f = files[i]; i++) {
      11.  
      12.     // Only process image files.
      13.     if (!f.type.match(‘image.*’)) {
      14.         continue;
      15.     }
      16.  
      17.     var reader = new FileReader();
      18.  
      19.     //capture the file information.
      20.     reader.onload = function(e) {
      21.         // Render thumbnail. e.target.result = the image content
      22.         // as a data URL
      23.        // create a span with CSS class=”thumb”, for nicer layout
      24.        var span = document.createElement(‘span’);
      25.        // Add an img src= in the span, with src= the dataURL of
      26.        // the image
      27.        span.innerHTML = “<img class=‘thumb’ src=‘” +
      28.                          e.target.result + “‘ alt=‘a picture’/>“;
      29.        // Insert the span in the output id=list
      30.        document.getElementById(‘list’).insertBefore(span, null);
      31.    };
      32.   // Read in the image file as a data URL.
      33.   reader.readAsDataURL(f);
      34.  }
      35. }

      Explanations:

        • Line 35: starts the reading of the file f. When f is read, the onload callback will be called.
        • Lines 25-31: we build, using the DOM API, a <span class=”thumb”>…</span> and inside we add an <img src=the data url> element with itssrc attribute equal to the url of the image that has been read (the image content as dataURL is in e.target.result). Finally, at line 31, we insert the span in the document before the current children of the <output id=”list”> element (declared at line 5).

      EXAMPLE 2: READ A SINGLE LOCAL IMAGE FILE AND USE IT WITH DRAWIMAGE IN A CANVAS

      Try it on JS Bin

      Errata: the above screenshot says “choose multiple files”, but the example only works with a single file.

      Source code extract:

      1. function drawImage(imageFile) {
      2.    var reader = new FileReader();
      3.  
      4.    //capture the file information.
      5.    reader.onload = function(e) {
      6.       // For drawing an image on a canvas we
      7.       // need an image object
      8.       var img = new Image();
      9.       // Even if the file has been read, decoding
      10.       // the dataURL format may take some time
      11.       // so we need to use the regular way of
      12.       // working with images: onload callback    
      13.       // that will be called after setting the src attribute
      14.       img.onload = function(e) {
      15.          // draw the image!
      16.          ctx.drawImage(img, 0, 0, 400, 400);
      17.       }
      18.       // e.target.result is the dataURL, so we set the
      19.       // src if the image with it. This will call
      20.       // asynchonously the onload callback
      21.       img.src= e.target.result;
      22.   };
      23.   // Read in the image file as a data URL.
      24.   reader.readAsDataURL(imageFile);
      25. }
      26. function readFileAndDraw(files) {
      27.     drawImage(files[0]);
      28. }

      Explanations:

      Remember how we worked with images on a canvas. We had to create an empty image object (line 8), set the src attribute of the image object (line 23), then use an image.onload callback (line 15), and we could only draw from inside the callback (line 17). This time, it’s exactly the same, except that the URL comes from e.target.result in the reader.onload callback (line 23).

      EXAMPLE 3 (ADVANCED): AN INSTAGRAM-LIKE PHOTO FILTER APPLICATION

      Another very impressive example, has been developed by @GeorgianaB, a student of the first iteration of this course (see her other creations/examples at http://codepen.io/giana/). This Web application reads local image files, draws them into a canvas element and proposes different filters. This example is given “as is” for those of you who would like to go further. Just click on the link (or on the image below) and look at the source code.

      Try this example online on gitHub (or click the screenshot below)

      Advertisements

      Leave a Reply

      Fill in your details below or click an icon to log in:

      WordPress.com Logo

      You are commenting using your WordPress.com account. Log Out / Change )

      Twitter picture

      You are commenting using your Twitter account. Log Out / Change )

      Facebook photo

      You are commenting using your Facebook account. Log Out / Change )

      Google+ photo

      You are commenting using your Google+ account. Log Out / Change )

      Connecting to %s