Repository: electron
Issue: [Feature Request]: Allow Generating Blobs from File Paths
Labels: enhancement :sparkles:

### Preflight Checklist

- [X] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [X] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [X] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a feature request that matches the one I want to file, without success.

### Problem Description

## Current solution

An electron preloader that isn't sandboxed has both the Blob class as well as the 'fs' module.
The following code does provide a means of going from a filepath to a Blob, and vice versa:

```js
const fs = require('fs');

// convert system file into blob
function fileToBlob(path, {bufferSize=64*1024}={}) {
	return new Promise((resolve,reject) => {
		// create incoming stream from file
		const stream = fs.createReadStream(path, {highWaterMark:bufferSize});

		// initialize empty blob
		var blob = new Blob([]);

		stream.on('data', buffer => {
			// append each chunk to blob by building new blob concatenating new chunk
			blob = new Blob([blob, buffer]);
		});
		stream.on('close', () => {
			// resolve with resulting blob
			resolve(blob);
		});
	});
}

// convert blob into system file
function blobToFile(blob,path, {bufferSize=64*1024}={}) {
	return new Promise((resolve,reject) => {
		// create outgoing stream to file
		const stream = fs.createWriteStream(path);

		stream.on('ready', async () => {
			// iterate chunks at a time
			for(let i=0; i<blob.size; i+=bufferSize) {
				// read chunk
				let slice = await blob.slice(i, i+bufferSize).arrayBuffer();

				// write chunk
				if(!stream.write(new Uint8Array(slice))) {
					// wait for next drain event
					await new Promise(resolve => stream.once('drain', resolve));
				}
			}

			// close file and resolve
			stream.on('close', () => resolve());
			stream.close();
		});
	});
}

module.exports = {
	fileToBlob,
	blobToFile,
};
```

## Issues with current solution

For small files, this has no downsides and works fine. But when working with multigigabyte files, this is extremely impractical and slow since it requires reading and copying the entire file, byte-by-byte.

## Chromium's existing mechanics

Now, Chromium already supports instant file-to-blob generation (a type that attaches the blob to the file directly; if the file is modified, the blob changes too). This is evident in the drag-and-drop API as well as the `<input type="file">` input.

In reverse, Chromium also supports fairly rapid blob-to-file generation as well. This can be seen when creating a blob url and then downloading it (it essentially downloads at os-level file-copy speed; so, sufficient, but not technically instant).

## Proposed addition

Since blobs are required for many renderer-context operations (like playing videos: https://stackoverflow.com/questions/59133969/play-a-blob-video-file), and is often the go-to for large files, it is becoming very essential to be able to generate a blob from a file instantly, using the same mechanism that Chromium uses in its drag-and-drop API.

In reverse, it would also be very helpful for applications that modify blobs (i.e., by slicing, generating, and rejoining into new blobs) to be able to export blobs at native speeds, again, using the same or a similar mechanism to Chromium. Specifically, although it can be done just by downloading a blob via a blob url, this mechanic would avoid the download file dialog.

### Proposed Solution

There are many ways this could be accomplished. A simple, straightforward method could simply be some kind of `blobToFile` / `fileToBlob` methods on the electron module, only available in the preloader or renderers with `nodeIntegration` enabled:

```js
const { fileBlob } = require('electron');

// generate blob from file
var blob = fileBlob.fileToBlob("C:/Users/Example/Desktop/foo.txt");

var newBlob = new Blob( [blob.slice(100,200), blob.slice(0,100)] );

// save blob to file
fileBlob.blobToFile("C:/Users/Example/Desktop/foo-reversed.txt");
```

Note, the above functions are written synchronously, but asynchronous methods would also suffice.

I am aware though that, since Blobs are not supported in node.js, a module such as 'fileBlob' would not be available in the node.js electron module without some kind of Blob polyfill. My main request is to provide a way to accomplish this in at least the renderer preloader environment.

### Alternatives Considered

I did find the following similar request exists, issue https://github.com/electron/electron/issues/749, which suggests that it be made possible to modify the value of a file input. Providing a solution to that issue also provides a solution to this one. Providing a solution to this one would not provide an exact solution to that one, but in most (or possibly all) cases would suffice.

### Additional Information

_No response_