How to Read Local Files with Javascript

There are some cases where a web application needs to read a local file from the user's system. This tutorial describes how to do so.

Demo

This demo reads a text file from the user's system :

% read

Download codes for demo

Concepts and Methods Used

  • The user will need the feature of choosing local files from his system. This can be done with the <input type="file" /> tag.
  • The user selected file can be read with the Javascript FileReader object.

Text Files vs Binary Files

All files can be categorized into two formats :

  • Text Files : Text files contain text data. We can open such files in a text editor, and easily get an idea of the contents of the file.

    Examples of text file formats are TXT, CSV, JSON, HTML etc.

  • Binary Files : Binary files contain data that only a custom application can understand. For example a JPEG file can only be opened by a photo reader application. If we open binary files in a text editor we will see garbage data.

    Other examples of binary file formats are EXE, PNG, MP4 etc.

The FileReader Object

The FileReader object, like the name suggests, reads a file. It asynchronously reads the file, and can read both text and binary file formats.

Futhermore it exposes events which makes it possible to know the read progress of the file, whether reading finished or an error occurred.

var reader = new FileReader();

Using FileReader to Read files

  • User chooses a file from his computer. Javascrpt validates the type/size of the file.

    <label for="file-input">Choose File</label>
    
    <!-- accept a text file -->
    <input type="file" id="file-input" style="display:none" accept="text/plain" />
    
    document.querySelector("#file-input").addEventListener('change', function() {
    	// list of selected files
    	var all_files = this.files;
    	if(all_files.length == 0) {
    		alert('Error : No file selected');
    		return;
    	}
    
    	// first file selected by user
    	var file = all_files[0];
    
    	// files types allowed
    	// we are reading text file in this example
    	var allowed_types = [ 'text/plain' ];
    	if(allowed_types.indexOf(file.type) == -1) {
    		alert('Error : Incorrect file type');
    		return;
    	}
    
    	// Max 2 MB allowed
    	var max_size_allowed = 2*1024*1024
    	if(file.size > max_size_allowed) {
    		alert('Error : Exceeded size 2MB');
    		return;
    	}
    
    	// file validation is successful
    	// we will now read the file
    });
    
    • Since each browser has its own user interface for <input type="file" />, we hide it with CSS, and use a <label> instead. Whenever the label is clicked, the file choose dialog will open up. This is an easy trick of doing the same thing, but with a better user interface.
    • We can use the accept attribute for the file input so that the file choose dialog will filter files of this extension.
    • The files property of a file input holds an array of files selected by the user. Each file can be validated for valid extension and size using type and size properties.
  • Now that the file is validated, we start reading the file.

    var reader = new FileReader();
    
    // file reading started
    reader.addEventListener('loadstart', function() {
        console.log('File reading started');
    });
    
    // file reading finished successfully
    reader.addEventListener('load', function(e) {
        var text = e.target.result;
    
        // contents of the file
        console.log(text);
    });
    
    // file reading failed
    reader.addEventListener('error', function() {
        alert('Error : Failed to read file');
    });
    
    // file read progress 
    reader.addEventListener('progress', function(e) {
        if(e.lengthComputable == true) {
        	var percent_read = Math.floor((e.loaded/e.total)*100);
        	console.log(percent_read + '% read');
        }
    });
    
    // read as text file
    reader.readAsText(file);
    
    • A new instance of FileReader is defined.
    • The load event handles successful reading of the file.
    • The error event handles error while reading the file.
    • The progress event handles reading progress of the file.
    • Since we're reading a text file here we use readAsText() method to read the file. If it was a binary file we could have used the readAsBinaryString() / readAsArrayBuffer() methods.

Reading Local Text File

Just as described above, we can read a text file with the readAsText() method.

Reading Local JSON File

A JSON file is also a text file format. We can read the file with readAsText() method and then parse the text as JSON using the JSON.parse() method.

reader.addEventListener('load', function(e) {
    // contents
    var text = e.target.result;

    // parse as JSON
    var json_str = JSON.parse(text);

    console.log(json_str);
});

Reading Local CSV File

A CSV file is also in text format. Once we get the text contents of the file, we can use the split() method to split the text into lines. Again on each line we split it into individual columns.

// rough algorithm to get CSV data from text
reader.addEventListener('load', function(e) {
    // contents as text
    var text = e.target.result;

    // will hold CSV data
    var data = [];

    // split by line breaks
    var rows = text.split("\r\n");

    for(var i=0; i<rows.length; i++) {
    	// split each row by comma
    	var row_columns = rows[i].split(",");

    	data.push(row_columns);
	}

	// CSV data
	console.log(data);
});

The external plugin PapaParse can also be used to parse CSV from text. It can handle large files and malformed CSV data also.

Reading Local Zip File

The ZIP file format is binary. You can get the binary data of the zip file with readAsBinaryString() / readAsArrayBuffer() methods and then read that according to the ZIP file specification.

Obviously writing a ZIP file reader from scratch is a complicated task. Fortunately there are external libraries such as JSZip to read a ZIP file.

Reading Local PDF File

The PDF file format is again binary in nature, and is quite complicated. However you can use the PDF.JS library to render local PDF files.

Useful Resources