file-services icon indicating copy to clipboard operation
file-services copied to clipboard

Support binary files

Open alisey opened this issue 4 years ago • 1 comments

IDirectoryContents interface used by createMemoryFs and populateDirectory only supports strings for file contents, which means it can't be used for binary files¹.

To represent binary files we could use an Uint8Array, which is already compatible with Buffer when using the native fs module:

Buffer.from([]) instanceof Uint8Array; // => true

const data: Uint8Array = fs.readFileSync('foo.txt');
fs.writeFileSync('bar.txt', data);
fs.writeFileSync('bar.txt', new Uint8Array([65, 66, 67]));

[1] Strictly speaking, JS strings can represent binary data without overhead, since they're sequences of 16-bit code units.

String.fromCharCode(0).charCodeAt(0) // => 0
String.fromCharCode(65535).charCodeAt(0) // => 65535
String.fromCharCode(65536).charCodeAt(0) // => 0, wrap around
String.fromCharCode(-1).charCodeAt(0) // 65535, wrap around

But this would require converting to and from unit8 arrays when working with readFile / writeFile, and we wouldn't be able to tell based on the string alone if conversion is required. So this sucks. And also files with an odd number of bytes can't be represented in this way.

alisey avatar Sep 30 '20 14:09 alisey

as an initial step, writeFile/Sync now accepts a Uint8Array

AviVahl avatar Dec 20 '20 17:12 AviVahl