User Tools

Site Tools


java-script:read-file

This is an old revision of the document!


How to read the content of a file (both web and node.js)

Read a file in web browser

The following script reads the content of a file selected by the user and then displays those contents in a <pre> element.
When the “Read File” button is clicked, the readFile function is called, which reads the file selected in the file input field and writes its contents to the fileContents element.

The read file operation using the FileReader API in a web browser is asynchronous. When you call readAsText (or any of the other read methods on a FileReader object), it starts the read operation and then immediately returns. The actual reading of the file happens in the background, and when it's done, the onload event is fired.

This is why you provide an onload callback function (or a promise) to handle the file data once it's available. If this operation were synchronous (i.e., blocking), the browser would become unresponsive until the read operation completes, which would lead to a poor user experience, especially for large files that might take a noticeable amount of time to read.

In the case of Node.js and the fs module, you have the option to read files synchronously using readFileSync, but it's generally recommended to use the asynchronous readFile for the reasons mentioned above. Asynchronous I/O operations allow the Node.js event loop to continue processing other tasks while waiting for the I/O operation to complete, leading to better performance and scalability.

When working with JavaScript in a web browser context, you can't freely access the user's file system due to strict security restrictions. This is a measure to protect users from potentially malicious actions that a website could perform, like reading sensitive data or modifying files without permission.

What this means is that JavaScript running in a browser does not have the ability to simply ask for a file or directory path and directly read the file content. The user must explicitly select the file to be read, typically via a file input control (<input type=“file”>).

When a user selects a file via such an input, the browser only provides your JavaScript code with a File object representing the chosen file. This doesn't disclose the file's actual path on the user's file system, again for security reasons.

Then you can use an object like FileReader to read the content of that file, but even here you don't have free rein. You can't write to the file or read other files that the user didn't explicitly select.

The only exception to this is when using JavaScript in a different context, like a server-side environment (Node.js, for example), or in browser extensions where you can request additional permissions. In those cases, JavaScript has more freedom to interact with the file system directly, because the context is more controlled and the user typically has to grant explicit permissions for such actions.

Using callback function (on onload event)

The FileReader object's onload event uses a callback function to handle the event when the file's content is fully loaded into memory.

read-file-web-callback.html
<!DOCTYPE html>
<html>
<head>
    <title>File Reader Example</title>
    <script>
        function readFile() {
            const fileInput = document.getElementById('myFile');
            const file = fileInput.files[0];
            const reader = new FileReader();
 
            reader.onload = function(e) {
                const contents = e.target.result;
                document.getElementById('fileContents').innerText = contents;
            };
 
            reader.readAsText(file);
        }
    </script>
</head>
<body>
    <input type="file" id="myFile">
    <button onclick="readFile()">Read File</button>
    <pre id="fileContents"></pre>
</body>
</html>

Using Promise

If you prefer using Promise instead of the onload event, you can create a wrapper function around the FileReader API that returns a promise.
A new function readAsText wraps the FileReader API and returns a promise. This promise resolves with the file's contents when the onload event is fired, and rejects if there's an error during the read operation (onerror).
Now the readFile function uses this readAsText function and handles the file content in a then clause, which gives a more modern, promise-based way of handling the file reading operation.

read-file-web-promise.html
<!DOCTYPE html>
<html>
<head>
    <title>File Reader Example</title>
    <script>
        function readFile() {
            const fileInput = document.getElementById('myFile');
            const file = fileInput.files[0];
 
            readAsText(file).then(contents => {
                document.getElementById('fileContents').innerText = contents;
            });
        }
 
        function readAsText(file) {
            return new Promise((resolve, reject) => {
                const reader = new FileReader();
 
                reader.onload = function(e) {
                    resolve(e.target.result);
                };
 
                reader.onerror = function(e) {
                    reject(e);
                };
 
                reader.readAsText(file);
            });
        }
    </script>
</head>
<body>
    <input type="file" id="myFile">
    <button onclick="readFile()">Read File</button>
    <pre id="fileContents"></pre>
</body>
</html>

Read a file in Node.js

First you should initialize the directory as a node.js es6+ module.

fileReader.js
import fs from 'fs/promises';
 
export async function readFile(filePath) {
    try {
        const data = await fs.readFile(filePath, 'utf8');
        console.log('File content:', data);
    } catch (err) {
        console.error('An error occurred:', err);
    }
}
index.js
import { readFile } from './fileReader.js';
 
const fileName = process.argv[2];
if (!fileName) {
    console.log('Please provide a file name as a command-line argument');
    process.exit(1);
}
 
readFile(fileName);

To run it:

node ./index.js C:/test.txt
java-script/read-file.1691182105.txt.gz · Last modified: 2023/08/04 23:48 by odefta