Creating Files through BlobBuilder

As Web sites transition more and more into Web applications, working with files in meaningful ways is becoming increasingly important. Starting with Platform Preview 2, IE10 includes support for the File API, enabling developers to read and slice files on the client. Platform Preview 4 adds support for BlobBuilder, a way for developers to create new files. IE10 also has two new methods that allow the user to save blobs to their computer, enabling great end-to-end experiences when working with client-resident data.

Over on the IE Test Drive, we have a fun piano demo showing off BlobBuilder and File API capabilities. When you press notes on the piano, the site constructs two files: an mp3 music file and an SVG file of the musical score. You can see how the size of both files change each time you press a note. Press the play button to listen to your song, or download either the music file or the SVG score file by pressing the links just above the piano keys. In the rest of this blog post I’ll go through how the demo works, focusing on the capabilities of BlobBuilder and File API.

Screen shot of the BlobBuilder piano-playing Test Drive demo.

BlobBuilder Capabilities

BlobBuilder, like the name implies, is a way to build blobs on the client. The main method to do this is append. The append function accepts three data types:

  • Blob objects
  • Plain text
  • Array Buffers

The piano demo creates the mp3 file by appending blobs together, using one blob for each note. The demo creates the SVG file of the musical score by appending text that contains the SVG source.

getBlob is another method available on the BlobBuilder object which returns a blob object containing all the items previously appended. Here is a very simple example that uses BlobBuilder to create a text file:

// The BlobBuilder constructor is prefixed in all browsers.

// Use MSBlobBuilder in IE, MozBlobBuilder in Firefox, and WebKitBlobBuilder in WebKit-based browsers.

var bb = new MSBlobBuilder();

 

bb.append("Hello World!");

var blob1 = bb.getBlob("text/plain");

One thing to note about the getBlob method is that when you call getBlob in IE10 and Firefox, it will clear out the contents of the BlobBuilder object, so the next time you call append it will be as if you were appending into a new BlobBuilder object. WebKit does not currently clear out the contents of the BlobBuilder after calling getBlob. Consider this example:

var bb = new MSBlobBuilder();

bb.append("Hello World!");

var blob1 = bb.getBlob("text/plain");

bb.append("BlobBuilder is great");

var blob2 = bb.getBlob("text/plain");

In all browsers, blob1 will contain the text “Hello World!”. However, blob2 will be different. In IE10 and Firefox, blob2 will contain the text “BlobBuilder is great” while in WebKit-based browsers it will contain the text “Hello World!BlobBuilder is great”. This discrepancy is still under discussion in the Web Applications working group.

Getting Blobs via XHR

The File API makes it easy to access files selected by the user, something I demonstrated in the Magnetic Poetry demo. This is great when you want to incorporate the users own data into your site. However, in the piano demo, I needed the note files to be built into the demo. When you want to work with blobs but you want to supply the data, you can use XHR.

New to IE10 is the XHR responseType property. The responseType property supports four values: blob, array buffer, text, and document. In the piano demo’s initialization method - getBlobs() - you’ll see the following:

var req = new XMLHttpRequest();

var url = 'PianoNotes/AllNotes2.mp3';

req.open('GET', url, false);

req.responseType = "blob";

req.onload = function () { /* ... */ };

req.send(null);

One thing you may notice is that the demo only makes a single XHR request. It only downloads one file which contains all the notes used in the demo. However, when you press a key in the demo, only a single note plays and the site appends only a single note to the mp3 file. To make that work, after downloading the file containing all the notes, the site slices the file using the File API slice method and extracts 24 individual notes. This is a great performance savings versus having to download 24 individual files.

Creating the Music File

Once I have a blob for each note in the demo, creating the mp3 file is easy. Each time you press a key I call:

musicBlobBuilder.append(noteBlob);

In order to update the file size, I get the blob and then get the file size.

var musicBlob = musicBlobBuilder.getBlob("audio/mp3");

// display musicBlob.size

Lastly because I know that the BlobBuilder object was cleared out when I called getBlob I just append the blob back in:

musicBlobBuilder.append(musicBlob);

Creating the SVG File

Each time you press a key in the demo, you see a note added to the musical score. The musical score is drawn by a single SVG element contained within a div with an id of “scoreContainer.” Each time you press a key, script runs which adds a note to the SVG element and then the SVG file is created by appending the source:

svgBlobBuilder.append(document.getElementById("scoreContainer").innerHTML);

var svgBlob = svgBlobBuilder.getBlob("image/svg+xml");

// display svgBlob.size

In this case, I don’t refill the svgBlobBuilder because I want to start with a clean slate the next time the user presses a key.

Saving Files to Disk

The last part of the demo is saving the files to disk. When you press the “Music File” and “Musical Score File” links on top of the piano keys you will be able to save the file though an experience that feels just like downloading a file:

Notification Bar shown in IE10 in response to a call to msOpenOrSaveBlog().

Note that the notification bar is not available in the Platform Previews. Instead, a save dialog is presented.

Each link calls either saveSong() or saveSheetMusic(). Looking into each of these methods will reveal that they use the msSaveOrOpenBlob function:

window.navigator.msSaveOrOpenBlob(svgBlob, "MusicScore.svg");

msSaveOrOpenBlob and msSaveBlob are two methods available in IE10 which let sites ask the user to save a blob to their computer.

Calling msSaveOrOpenBlob will provide an option on the notification bar to open the file in addition to saving or canceling. Calling msSaveBlob only provides the option to save the file or cancel. Though these functions are not yet included in any standard, we believe they are extremely useful for writing end to end scenarios with blob data and hope that they might become a standard at some point.

Creating the Piano demo was a fun experience and I’m excited to see how you will use BlobBuilder. Let us know what you think!

—Sharon Newman, Program Manager, Internet Explorer

MSDN Magazine February Issue Preview

In a few days the February issue of MSDN Magazine should be hitting mailboxes and Web browsers alike. In other words, it's time for an MSDN Magazine issue preview. Here's what's cooking for the shortest month of the year.

Our lead feature in February is "Asynchronous Programming with C++ Using PPL," by Artur Laksberg. This feature looks at the powerful asynchronous talents of C++ and how they can be used to create more efficient and scalable applications. And as Laksberg points out, moving to asynchronous development is a great idea for anyone looking to take advantage of the unique capabilities of Windows Runtime and Windows 8. This piece is also a nice complement to the trio of features we published on asynchrony in C# back in October.

February sees a continuation of a couple ongoing feature series, including the next installment of our Building HTML5 Apps series. John Dyer steps in for Brandon Satrom to pen "Practical Cross-Browser HTML5 Audio and Video," which explores the powerful media handling capabilities of HTML5. In addition to recommending useful libraries, Dyer shows how to work around issues like uneven browser support for HTML5 tags and media types. Also this month we see the latest in our Windows Phone feature series. Cheryl Simmons offers useful guidance in her feature, "Get Your Windows Phone Applications in the Marketplace Faster." The piece shows how to properly optimize Windows Phone apps so they will pass muster in Microsoft's Marketplace assessment process. Finally, we close out the three-part NuGet series, with Clark Sell's feature "Creating a NuGet Gallery."

The February issue touches on a number of strategic Microsoft platforms. In addition to the Windows Phone coverage noted above, this issue includes the feature "Building a Massively Scalable Platform for Consumer Devices on Windows Azure," by Bruno Terkaly and Ricardo Villalobos. The piece demonstrates the scalability and interoperability of Microsoft's cloud platform, showing how to use Windows Azure-hosted RESTful Web services to stream video to a large number of diverse mobile clients. ASP.NET MVC developers also earn a nod, with Jess Chadwick's "Features and Foibles of ASP.NET MVC Model Binding." As Chadwick writes, the features "will take you deep into the heart of the ASP.NET MVC model binding subsystem, showing each layer of the model binding framework and the various ways you can extend the model binding logic to meet your application’s needs."

Finally, our February feature selection includes "What’s New in Windows Workflow 4.5," by Leon Welicki, an overview of the many changes and improvements in the latest version of WF in .NET Framework 4.5.

The big news in our column lineup this month is the return of John Papa, who until 2009 wrote our popular Data Points column. He returns this month to write the new Client Insight column, which focuses on technologies and issues related to client-side development. HTML5, JavaScript, WPF, Silverlight... if it's relevant to client app development, it's relevant to his column. Given Papa's background in both data and client development, it's fitting that his inaugural column looks at the unique data binding talents of the Knockout JavaScript library. You can also read more about Papa’s return in this months Editor’s Note column.

Speaking of data, Julie Lerman's Data Points column dwells on Entity Framework 4.2 DbContext class, which she describes as a "wrapper around ObjectContext that exposes the most commonly used features of ObjectContext." It also streamlines many frequent-but-complex tasks when coding directly with ObjectContext. Joseph Fultz offers a look at Windows Azure Deployment Domains in his Forecast: Cloudy column this month, while Ted Neward's column The Working Programmer explores Tropo, a free, cloud-hosted, voice-and-SMS solution.

As ever, James McCaffrey is exploring the hard edges of programming in his Test Run column. This month he dives into an "Ant Colony Optimization," an algorithm that uses artificial intelligence techniques based on the pheromone-laying behavior of ants. Seriously. It's the latest in McCaffrey's fascinating explorations of, as he puts it, "optimization algorithms based on the behavior of natural systems."

In our January issue, Charles Petzold's long-running UI Frontiers column appeared under its new name, Touch and Go. The change reflects Petzold's ongoing focus on Windows Phone, mobile and touch-based application development. This month, Petzold shows how to play music files in the background from a Windows Phone 7.5 application and highlights some interesting quirks in the implementation of background audio.

As ever, MSDN Magazine closes with David Platt and his Don’t Get Me Started column. Look for his musings on smartphones and the odd way in which they both pull people together and push them apart.

Got a topic, issue or technology you’d like to see addressed in MSDN Magazine? Please let me know! Leave a comment here or email me at mmeditor@microsoft.com.

A Conversation with Charles Petzold

Earlier this month I posted a blog post that followed up on the Editor's Note column (A Quarter Century and Counting) appearing in the January issue of MSDN Magazine. In the column, I recounted Charles Petzold's amazing 25-year run as a regular writer and columnist for the magazine. In this, the second of two blog posts about that column, I follow up our initial conversation with a few additional questions.

Desmond: Earlier you mentioned tablet and phone as a third revolution. Of course, your Touch and Go column (previously, UI Frontiers) focuses on Windows Phone and Windows touch-based devices and applications. Given what you observed with the GUI and Internet/Web revolutions, any thoughts on what might be ahead in the mobile/touch space?

Petzold: Many years ago I read on article in a major news magazine about a new fad that was sweeping Japan. The author of this article was certain this fad couldn’t possibly make it in America because American families would simply not sit around the living room singing songs together while the lyrics flashed by on the TV set. Well, as we know, karaoke did become popular in America, but in a completely different setting -- the bar rather than the living room.

The way in which technology evolves and adapts is very mysterious to me, which is why I stay away from industry punditry. The only expectation I have is of the unexpected.

Desmond: You talked about the importance of social connections between PC Magazine and MSJ/MSDN Magazine. Beyond the obvious shared roots and interests, it seems like physical proximity really sustained those links. Do you believe Internet-borne interaction can sustain the “socializing aspect” that you found so vital to the magazine?

Petzold: I’m on Facebook every day, and it’s fun to exchange thoughts and opinions with friends and “friends.” But Facebook is a very poor imitation of actual human contact. Tony Rizzo once organized a dinner with about 10 MSJ authors and Bill Gates in a private room of a sushi restaurant, and we basically spent a couple hours eating sushi and listening to Bill talk about the computer industry. I don’t see how that experience could possibly be imitated in an online chat room.

What’s most revealing on Facebook is how fragmented the computer industry has become. Everybody seems to be working on something different, and it’s impossible for any one person to be familiar with all these different technologies. We’ve all become specialists. There’s no longer an industry event like Comdex that virtually everybody attends, no longer books that everybody reads, no longer languages that everyone speaks.

Desmond: You know, there was a time, not at all long ago, when we all read the same newspapers and watched the same TV shows (at the same time, even). Those common touch points have faded as the Internet has enabled personalized media delivery and a host of narrowly focused information sources.

But in the arena of software development, I take your point: We live in an era of layered abstraction and vast frameworks. So the question is, where and how can developers sustain a common ground? Is it in the higher level logic and the technique of problem solving, project management and programming methodology?

Petzold: This is a problem, and it doesn’t seem to be getting any better. But the extreme biodiversity that exists now is perhaps an indication that the art and engineering of computer programming is still in its infancy. And that suggests we need to keep our minds open -- to evaluate new frameworks and programming languages with the thought that they may actually be better than what we’re using now.

I had this experience just recently when working with the new asynchronous file I/O classes in Windows 8. If the best is yet to come, magazines such as MSDN have an obligation to help keep developers informed of the cutting edges of programming technologies.

Five most popular posts on the Excel blog in 2011

It's still January. There's still time to share the most popular posts on the Excel blog in 2011. Thanks for reading them! Can't remember all those Excel keyboard shortcuts? Now you don't have to! There are a lot of keyword shortcuts in Excel. You can scroll through a long list of them on Office.com, or you can download Quick Reference Cards from our blog and pin them to your corkboard. There are cards for Keyboard shortcuts with theCtrl keys , Keyboard shortcuts with Function keys , and Miscellaneous...(read more)

How to save your Access SharePoint password

Recently, someone posted a comment on IT Impact Inc.'s blog asking how to get SharePoint to remember his password when he logged in via Access. He wanted to avoid having to log in every time. Ben Clothier, a Senior Access Developer at IT Impact, knew the answer. He wrote a detailed blog post (with plenty of screenshots) that we'd like to share with you. ITImpact has been building custom databases with Microsoft Access since 1994, serving customers around the world. Ben Clothier has been Microsoft...(read more)

New book: Microsoft Manual of Style, Fourth Edition

Editors, writers, and content creators: get in line to purchase the newest edition of the Microsoft Manual of Style ! Now in its fourth edition, the Microsoft Manual of Style provides essential style and usage guidance for everyone who writes about computer...(read more)

New book: Microsoft Manual of Style, Fourth Edition

Editors, writers, and content creators: get in line to purchase the newest edition of the Microsoft Manual of Style ! Now in its fourth edition, the Microsoft Manual of Style provides essential style and usage guidance for everyone who writes about computer...(read more)

New book: Microsoft Manual of Style, Fourth Edition

Editors, writers, and content creators: get in line to purchase the newest edition of the Microsoft Manual of Style ! Now in its fourth edition, the Microsoft Manual of Style provides essential style and usage guidance for everyone who writes about computer...(read more)

Debugging IndexedDB Applications

IndexedDB is a W3C Working Draft that enables JavaScript developers to store, search, and retrieve data on the user's local client, even when Internet connectivity is disabled. This blog post describes IDBExplorer, a tool we use internally to debug IndexedDB applications. IDBExplorer lets you view database schemas, object store content, and index details.

Exploring the tool with an example IndexedDB App

To illustrate, I created an application that tracks my New Year’s resolutions using IndexedDB. It stores and accesses my resolutions locally (on the system browsing the Web page) and lets me add or edit them. The “Done That!” button removes the selected resolution from the list and removes its internal representation from the database.

Partial screen shot of an application that tracks New Year’s resolutions using IndexedDB.

IndexedDB defines a database as a container of information. Each database contains object stores, which are repositories for JavaScript objects. Each object contains attributes which can be queried using the API. If you're familiar with relational databases, object stores can be equated to tables and each JavaScript object in an object store represents a record. However, the objects stored in an IndexedDB object store are treated as opaque entities. In addition, these objects do not have to contain the same properties.

If a JavaScript object is analogous to a relational database record, then the properties of that object can be thought of as columns (or fields) in a table. As a result, IndexedDB allows you to define indexes that identify object properties that can be used to search the records in an object store. Thus, indexes allow you to traverse and search IndexedDB data using the attribute values on a JavaScript object.

IndexedDB allows each Domain to have multiple databases. This example uses one database: “NewYear.” The app stores my resolutions in an object store named “Resolutions” inside the NewYear database. Each resolution is a JavaScript object with the following attributes:

  • priorityId: Separates resolutions into different priorities
  • name: Name of the resolution
  • occurrenceId: Tracks how frequently the action of the resolution must be performed
  • dueDate: Completion date of the resolution
  • createdDate: Internal date when the resolution was added to the object store
  • categoryId: Defines the type of activity for a resolution

Notice that not all attributes are visible from the application’s UI. In some cases, they are only internally used (e.g. createdDate).

Here’s how the IDBExplorer tool displays the contents of the “Resolutions” object store:

Partial screen shot of the IDBExplorer tool displaying the contents of the “Resolutions” object store.

The “Resolutions” object store also contains an index on the priorityId attribute named “priorityId,” which allows the app to query objects using the priorityId property. The descriptions for the each priorityId value can be found inside the “Priorities” object store and the descriptions for the occurrenceId values can be found inside the “Occurrences” object store. Likewise, the descriptions for the categoryId values can be found inside the “Categories” object store.

The tool uses a tree hierarchy to illustrate these relationships:

Screen shot of the IDBExplorer tool showing there are five resolutions in the database.

The IDBExplorer tool shows there are five resolutions in my database (two high priority tasks, two medium priorities, and one low priority).

Using the application, I can add a new resolution:

Partial screen shot of the New Year’s Resolutions application showing adding a resolution.

The app retrieves the values for Occurrence, Priority, and Category fields from their respective object stores using cursors and displays them to the user. The IDBExplorer tool lets you see how these values exist in the object store. For example, selecting the Categories object store displays the available categories and their descriptions:

Screen shot of the IDBExplorer tool showing how values exist in the object store.

You can update a resolution by selecting it in the “WorkOn” screen and choosing “Edit.” After making any changes, selecting the “Update” button will commit the changes and update the values in the “Resolutions” object store.

Partial screen shot of the New Year’s Resolutions application showing updating a resolution by selecting it in using the “WorkOn” screen.

Using IDBExplorer in your Applications

You can include the IDBExplorer tool in your Metro style app or Web site. However, we recommend you not deploy the tool with your app.

To add the tool to your site, copy and unzip the content of the IDBExplorer package into your site. Your application will need to link to the IDBExplorer.html file contained inside the IDBExplorer folder using either an iframe element or a new window.

In our example, we decided to host IDBExplorer inside an iframe element. . However, for normal development we recommend hosting this URI inside a new window. This will allow you to have a side-by-side experience when debugging your database and application without affecting your site's user interface.

When hosting IDBExplorer, you need to pass the database name using the query string. In this example, this was done using the src attribute of the iframe element:

<iframe id="debuggerId" class="debuggerContainer" src="IDBExplorer/IDBExplorer.html?name=NewYear"></iframe>

When planning to host this functionality in a Metro style app, remember that Metro-style apps run fullscreen. As a result, you should navigate to this URL, rather than opening a new window (you will need to add a Back button to the IDBExplorer.html file in order to be able to return to your application). Alternatively, you can add an iframe element and display the tool in it.

Enjoy the tool and let us know what you think!

—Israel Hilerio, Ph.D., Principal Program Manager, Internet Explorer

Debugging IndexedDB Applications

IndexedDB is a W3C Working Draft that enables JavaScript developers to store, search, and retrieve data on the user's local client, even when Internet connectivity is disabled. This blog post describes IDBExplorer, a tool we use internally to debug IndexedDB applications. IDBExplorer lets you view database schemas, object store content, and index details.

Exploring the tool with an example IndexedDB App

To illustrate, I created an application that tracks my New Year’s resolutions using IndexedDB. It stores and accesses my resolutions locally (on the system browsing the Web page) and lets me add or edit them. The “Done That!” button removes the selected resolution from the list and removes its internal representation from the database.

Partial screen shot of an application that tracks New Year’s resolutions using IndexedDB.

IndexedDB defines a database as a container of information. Each database contains object stores, which are repositories for JavaScript objects. Each object contains attributes which can be queried using the API. If you're familiar with relational databases, object stores can be equated to tables and each JavaScript object in an object store represents a record. However, the objects stored in an IndexedDB object store are treated as opaque entities. In addition, these objects do not have to contain the same properties.

If a JavaScript object is analogous to a relational database record, then the properties of that object can be thought of as columns (or fields) in a table. As a result, IndexedDB allows you to define indexes that identify object properties that can be used to search the records in an object store. Thus, indexes allow you to traverse and search IndexedDB data using the attribute values on a JavaScript object.

IndexedDB allows each Domain to have multiple databases. This example uses one database: “NewYear.” The app stores my resolutions in an object store named “Resolutions” inside the NewYear database. Each resolution is a JavaScript object with the following attributes:

  • priorityId: Separates resolutions into different priorities
  • name: Name of the resolution
  • occurrenceId: Tracks how frequently the action of the resolution must be performed
  • dueDate: Completion date of the resolution
  • createdDate: Internal date when the resolution was added to the object store
  • categoryId: Defines the type of activity for a resolution

Notice that not all attributes are visible from the application’s UI. In some cases, they are only internally used (e.g. createdDate).

Here’s how the IDBExplorer tool displays the contents of the “Resolutions” object store:

Partial screen shot of the IDBExplorer tool displaying the contents of the “Resolutions” object store.

The “Resolutions” object store also contains an index on the priorityId attribute named “priorityId,” which allows the app to query objects using the priorityId property. The descriptions for the each priorityId value can be found inside the “Priorities” object store and the descriptions for the occurrenceId values can be found inside the “Occurrences” object store. Likewise, the descriptions for the categoryId values can be found inside the “Categories” object store.

The tool uses a tree hierarchy to illustrate these relationships:

Screen shot of the IDBExplorer tool showing there are five resolutions in the database.

The IDBExplorer tool shows there are five resolutions in my database (two high priority tasks, two medium priorities, and one low priority).

Using the application, I can add a new resolution:

Partial screen shot of the New Year’s Resolutions application showing adding a resolution.

The app retrieves the values for Occurrence, Priority, and Category fields from their respective object stores using cursors and displays them to the user. The IDBExplorer tool lets you see how these values exist in the object store. For example, selecting the Categories object store displays the available categories and their descriptions:

Screen shot of the IDBExplorer tool showing how values exist in the object store.

You can update a resolution by selecting it in the “WorkOn” screen and choosing “Edit.” After making any changes, selecting the “Update” button will commit the changes and update the values in the “Resolutions” object store.

Partial screen shot of the New Year’s Resolutions application showing updating a resolution by selecting it in using the “WorkOn” screen.

Using IDBExplorer in your Applications

You can include the IDBExplorer tool in your Metro style app or Web site. However, we recommend you not deploy the tool with your app.

To add the tool to your site, copy and unzip the content of the IDBExplorer package into your site. Your application will need to link to the IDBExplorer.html file contained inside the IDBExplorer folder using either an iframe element or a new window.

In our example, we decided to host IDBExplorer inside an iframe element. . However, for normal development we recommend hosting this URI inside a new window. This will allow you to have a side-by-side experience when debugging your database and application without affecting your site's user interface.

When hosting IDBExplorer, you need to pass the database name using the query string. In this example, this was done using the src attribute of the iframe element:

<iframe id="debuggerId" class="debuggerContainer" src="IDBExplorer/IDBExplorer.html?name=NewYear"></iframe>

When planning to host this functionality in a Metro style app, remember that Metro-style apps run fullscreen. As a result, you should navigate to this URL, rather than opening a new window (you will need to add a Back button to the IDBExplorer.html file in order to be able to return to your application). Alternatively, you can add an iframe element and display the tool in it.

Enjoy the tool and let us know what you think!

—Israel Hilerio, Ph.D., Principal Program Manager, Internet Explorer