Read local file and display contents using javascript

Alec Jacobson

February 18, 2011

weblog/

The upcoming File API for web applications means that HTML 5 pages will be able to ask user for a local file (a file on the user's computer) and use the data in that file directly. It's amazing that this hasn't really existed before. Web applications either used http requests to send the file to the server then have the server send it back, or use super hacky solutions that typically involved using Java or Flash applets to piggy-back into the local file. Unfortunately, this is not fully supported by browsers. It seems Firefox and Chrom(e|ium) support this File API already, but Safari and Webkit don't yet. IE may never. Check it out:

Progress:

File contents:

Here's the source as a full HTML page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<meta http-equiv='Content-type' content='text/html;charset=UTF-8' >
		<script>
function startRead()
{
  // obtain input element through DOM 
  
  var file = document.getElementById('file').files[0];
  if(file)
	{
    getAsText(file);
  }
}

function getAsText(readFile)
{
	var reader;
	try
	{
    reader = new FileReader();
	}catch(e)
	{
		document.getElementById('output').innerHTML = 
			"Error: seems File API is not supported on your browser";
	  return;
  }
  
  // Read file into memory as UTF-8      
  reader.readAsText(readFile, "UTF-8");
  
  // Handle progress, success, and errors
  reader.onprogress = updateProgress;
  reader.onload = loaded;
  reader.onerror = errorHandler;
}

function updateProgress(evt)
{
  if (evt.lengthComputable)
	{
    // evt.loaded and evt.total are ProgressEvent properties
    var loaded = (evt.loaded / evt.total);
    if (loaded < 1)
		{
      // Increase the prog bar length
      // style.width = (loaded * 200) + "px";
			document.getElementById("bar").style.width = (loaded*100) + "%";
    }
  }
}

function loaded(evt)
{
  // Obtain the read file data    
  var fileString = evt.target.result;
  document.getElementById('output').innerHTML = fileString;
		document.getElementById("bar").style.width = 100 + "%";
}

function errorHandler(evt)
{
  if(evt.target.error.code == evt.target.error.NOT_READABLE_ERR)
	{
    // The file could not be read
		document.getElementById('output').innerHTML = "Error reading file..."
  }
}
		</script>
	</head>

	<body>
		<input id="file" type="file" multiple onchange="startRead()">
		<h3>Progress:</h3>
		<div style="width:100%;height:20px;border:1px solid black;">
		<div id="bar" style="background-color:#45F;width:0px;height:20px;"></div>
		</div>
		<h3>File contents:</h3>
		<pre>
			<code id="output">
			</code>
		</pre>
	</body>
</html>
Note: This WILL NOT WORK if you load your html page as a local file. Meaning the address starts with file:/// instead of http://, for some reason the page must be served to the browser from a server. Source