file-services
file-services copied to clipboard
Support binary files
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.
as an initial step, writeFile/Sync now accepts a Uint8Array