Native Client

File IO

FileIO does not work the same way in Native Client as it does in a standard desktop application. For security reasons, Chrome does not let you randomly read/write to things. Instead, Chrome provides an obfuscated, restricted area on disk to which you can safely read and write.

Loading files in a Native Client module

There are two ways to load files in a Native Client module: the URLLoader API and the File IO API.

Pepper URLLoader API

Your Native Client module (.nexe file) is embedded in a web page, which means that the module is not running directly on a desktop and does not have access to the file system. One way to load files is to use the Pepper URLLoader API to directly access files that appear to be "on the server" where the .nexe file is hosted. The SDK includes an example, geturl_handler, that shows how to do this. The URLLoader API fetches an asset and returns a binary stream that you can do with as you see fit. Since this technique uses HTTP to get an asset, Chrome actively caches the asset, which means that subsequent calls to fetch the asset should pull the asset from the local cache rather than go out over the Internet again. The upside of this technique is that Chrome does the caching on your behalf; the downside is that you're at the whim of the cache and have no guarantee of a cache hit.

Pepper File IO API

A second way to load files is to use the Pepper File IO API. The File IO API gives you access to network locations (like GetURL), but in addition it also gives you access to the local disk so that you can write your file data to the disk and manage the caching yourself. More specifically, you get access to a sandboxed local data store that you can read and write to freely. This works well for applications where you can download binary assets into the local data store and stream the data from disk into the application, because you can control the caching yourself. Check out the Pong game for an example of how to read and write using the Pepper File IO API.

Tips for your file manager

With either of the techniques described above, you can imagine that file IO does not lend itself to a blocking model. As a result, functions like fread/fwrite don't work as intended. To handle file IO in Native Client you must adjust your file manager paradigm to an asynchronous model.

To keep their code sane, many developers hook up a Native Client backend to their file manager to stream in the data file they want to some temporary in-memory location, and then override fread to access the in-memory data rather than hitting the disk. The Native Client team is hoping to provide a more robust solution in the future, but for now this should get you through.

Another important limitation to keep in mind is that calls to the Pepper File IO API must be done only from the main thread.

Note also that it's a bad idea to try to emulate a blocking fread using the File IO system! Many people have tried this and failed. Their solution was to kick off a read and spin-loop until the read completes. That's a problem because the file IO processing isn't serviced until the start of the next frame. So for example, there is a standard frame of NaCl processing that's got overhead from the page, then Pepper, then your module. If you kick off an fread in your module, it won't get serviced until the next Pepper processing phase. In general, you should write your file IO system to take into account at least one frame of delay.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.