A memory-based implementation of Node.js fs module for testing purposes
Overall
score
96%
Low-level file descriptor operations for fine-grained control over file access, positioning, and data manipulation. File descriptors provide precise control over file operations with manual buffer management.
Open files and obtain file descriptors for low-level operations.
/**
* Synchronously open a file and return a file descriptor
* @param path - File path to open
* @param flags - File open flags (string or number)
* @param mode - File mode for newly created files
* @returns File descriptor number
*/
openSync(path: string | Buffer, flags: string | number, mode?: number): number;
/**
* Asynchronously open a file and return a file descriptor
* @param path - File path to open
* @param flags - File open flags (string or number)
* @param mode - File mode for newly created files
* @param callback - Completion callback with file descriptor
*/
open(path: string | Buffer, flags: string | number, mode?: number, callback?: (err?: Error, fd?: number) => void): void;
open(path: string | Buffer, flags: string | number, callback: (err?: Error, fd?: number) => void): void;File Flags:
'r' - Open for reading (file must exist)'r+' - Open for reading and writing (file must exist)'w' - Open for writing (truncates file or creates new)'wx' - Open for writing exclusively (fails if file exists)'w+' - Open for reading and writing (truncates or creates)'wx+' - Open for reading and writing exclusivelyUsage Examples:
// Open file for reading
const fd = fs.openSync('/data.txt', 'r');
// Open for writing with specific mode
const writeFd = fs.openSync('/output.txt', 'w', 0o644);
// Open exclusively (fail if exists)
try {
const exclusiveFd = fs.openSync('/unique.txt', 'wx');
console.log('File opened exclusively');
} catch (err) {
console.log('File already exists');
}
// Async file opening
fs.open('/async.txt', 'r+', (err, fd) => {
if (!err) {
console.log('File opened with fd:', fd);
// Remember to close the file descriptor
fs.close(fd, () => {});
}
});
// Promise-based opening
const fd = await fs.promises.open('/promise.txt', 'w');Close file descriptors to free system resources.
/**
* Synchronously close a file descriptor
* @param fd - File descriptor to close
*/
closeSync(fd: number): void;
/**
* Asynchronously close a file descriptor
* @param fd - File descriptor to close
* @param callback - Completion callback
*/
close(fd: number, callback: (err?: Error) => void): void;Usage Examples:
// Open, use, and close file
const fd = fs.openSync('/temp.txt', 'w');
try {
// ... use file descriptor
fs.writeSync(fd, 'Hello World');
} finally {
fs.closeSync(fd); // Always close
}
// Async close
fs.open('/file.txt', 'r', (err, fd) => {
if (!err) {
// ... use fd
fs.close(fd, (closeErr) => {
if (!closeErr) {
console.log('File closed successfully');
}
});
}
});Read data from files using file descriptors with precise buffer control.
/**
* Synchronously read data from a file descriptor into a buffer
* @param fd - File descriptor to read from
* @param buffer - Buffer to write data into
* @param offset - Offset in buffer to start writing
* @param length - Number of bytes to read
* @param position - Position in file to read from (null for current position)
* @returns Number of bytes read
*/
readSync(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null): number;
/**
* Asynchronously read data from a file descriptor into a buffer
* @param fd - File descriptor to read from
* @param buffer - Buffer to write data into
* @param offset - Offset in buffer to start writing
* @param length - Number of bytes to read
* @param position - Position in file to read from (null for current position)
* @param callback - Completion callback with bytes read
*/
read(fd: number, buffer: Buffer, offset: number, length: number, position?: number | null, callback?: (err?: Error, bytesRead?: number) => void): void;Usage Examples:
// Read file content into buffer
const fd = fs.openSync('/data.txt', 'r');
const buffer = Buffer.alloc(1024);
try {
const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);
const content = buffer.subarray(0, bytesRead).toString('utf8');
console.log('Read content:', content);
} finally {
fs.closeSync(fd);
}
// Read from specific position
const fd2 = fs.openSync('/large-file.txt', 'r');
const chunk = Buffer.alloc(100);
const bytesRead = fs.readSync(fd2, chunk, 0, 100, 500); // Read 100 bytes from position 500
fs.closeSync(fd2);
// Async reading
fs.open('/async-read.txt', 'r', (err, fd) => {
if (err) return;
const buffer = Buffer.alloc(256);
fs.read(fd, buffer, 0, buffer.length, null, (readErr, bytesRead) => {
if (!readErr) {
const data = buffer.subarray(0, bytesRead);
console.log('Read data:', data.toString());
}
fs.close(fd, () => {});
});
});Write data to files using file descriptors with precise positioning control.
/**
* Synchronously write data from a buffer or string to a file descriptor
* @param fd - File descriptor to write to
* @param buffer - Buffer or string containing data to write
* @param offset - Offset in buffer to start reading from (for Buffer)
* @param length - Number of bytes to write (for Buffer)
* @param position - Position in file to write to (null for current position)
* @returns Number of bytes written
*/
writeSync(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number | null): number;
writeSync(fd: number, string: string, position?: number | null, encoding?: string): number;
/**
* Asynchronously write data from a buffer or string to a file descriptor
* @param fd - File descriptor to write to
* @param buffer - Buffer or string containing data to write
* @param offset - Offset in buffer to start reading from
* @param length - Number of bytes to write
* @param position - Position in file to write to (null for current position)
* @param callback - Completion callback with bytes written
*/
write(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number | null, callback?: (err?: Error, bytesWritten?: number) => void): void;
write(fd: number, string: string, position?: number | null, encoding?: string, callback?: (err?: Error, bytesWritten?: number) => void): void;Usage Examples:
// Write string to file
const fd = fs.openSync('/output.txt', 'w');
try {
const bytesWritten = fs.writeSync(fd, 'Hello, World!');
console.log(`Wrote ${bytesWritten} bytes`);
} finally {
fs.closeSync(fd);
}
// Write buffer to specific position
const fd2 = fs.openSync('/patchable.txt', 'r+');
const data = Buffer.from('patched');
fs.writeSync(fd2, data, 0, data.length, 10); // Write at position 10
fs.closeSync(fd2);
// Write with encoding
const fd3 = fs.openSync('/unicode.txt', 'w');
fs.writeSync(fd3, 'Hello 世界', 0, 'utf8');
fs.closeSync(fd3);
// Async writing
fs.open('/async-write.txt', 'w', (err, fd) => {
if (err) return;
const buffer = Buffer.from('Async data');
fs.write(fd, buffer, 0, buffer.length, null, (writeErr, bytesWritten) => {
if (!writeErr) {
console.log(`Wrote ${bytesWritten} bytes`);
}
fs.close(fd, () => {});
});
});Get file information using file descriptors.
/**
* Synchronously get file statistics using a file descriptor
* @param fd - File descriptor
* @returns Stats object with file information
*/
fstatSync(fd: number): Stats;
/**
* Asynchronously get file statistics using a file descriptor
* @param fd - File descriptor
* @param callback - Completion callback with stats
*/
fstat(fd: number, callback: (err?: Error, stats?: Stats) => void): void;
interface Stats {
isFile(): boolean;
isDirectory(): boolean;
isSymbolicLink(): boolean;
size: number;
mode: number;
uid: number;
gid: number;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
// ... other properties
}Usage Examples:
// Get file stats using file descriptor
const fd = fs.openSync('/file.txt', 'r');
try {
const stats = fs.fstatSync(fd);
console.log(`File size: ${stats.size} bytes`);
console.log(`Is file: ${stats.isFile()}`);
console.log(`Modified: ${stats.mtime}`);
} finally {
fs.closeSync(fd);
}
// Async stats
fs.open('/data.txt', 'r', (err, fd) => {
if (err) return;
fs.fstat(fd, (statErr, stats) => {
if (!statErr) {
console.log('File info:', {
size: stats.size,
isFile: stats.isFile(),
modified: stats.mtime
});
}
fs.close(fd, () => {});
});
});Change file permissions using file descriptors.
/**
* Synchronously change file permissions using a file descriptor
* @param fd - File descriptor
* @param mode - New file mode (permissions)
*/
fchmodSync(fd: number, mode: number | string): void;
/**
* Asynchronously change file permissions using a file descriptor
* @param fd - File descriptor
* @param mode - New file mode (permissions)
* @param callback - Completion callback
*/
fchmod(fd: number, mode: number | string, callback?: (err?: Error) => void): void;Usage Examples:
// Change file permissions via file descriptor
const fd = fs.openSync('/secure.txt', 'r+');
try {
fs.fchmodSync(fd, 0o600); // Owner read/write only
console.log('Permissions changed');
} finally {
fs.closeSync(fd);
}
// Async permission change
fs.open('/data.txt', 'r+', (err, fd) => {
if (err) return;
fs.fchmod(fd, '644', (chmodErr) => {
if (!chmodErr) {
console.log('Permissions updated');
}
fs.close(fd, () => {});
});
});Force file data to be written to storage.
/**
* Synchronously force file data and metadata to be written to storage
* @param fd - File descriptor
*/
fsyncSync(fd: number): void;
/**
* Synchronously force file data (not metadata) to be written to storage
* @param fd - File descriptor
*/
fdatasyncSync(fd: number): void;
/**
* Asynchronously force file data and metadata to be written to storage
* @param fd - File descriptor
* @param callback - Completion callback
*/
fsync(fd: number, callback?: (err?: Error) => void): void;
/**
* Asynchronously force file data (not metadata) to be written to storage
* @param fd - File descriptor
* @param callback - Completion callback
*/
fdatasync(fd: number, callback?: (err?: Error) => void): void;Usage Examples:
// Ensure data is written to disk
const fd = fs.openSync('/critical.txt', 'w');
try {
fs.writeSync(fd, 'Important data');
fs.fsyncSync(fd); // Force write to disk
console.log('Data synchronized to storage');
} finally {
fs.closeSync(fd);
}
// Data-only sync (faster than fsync)
fs.fdatasyncSync(fd); // Sync data but not metadata
// Async sync
fs.open('/log.txt', 'w', (err, fd) => {
if (err) return;
fs.write(fd, 'Log entry', (writeErr) => {
if (writeErr) return;
fs.fsync(fd, (syncErr) => {
if (!syncErr) {
console.log('Log entry synchronized');
}
fs.close(fd, () => {});
});
});
});// Always close file descriptors
function safeFileOperation(path) {
const fd = fs.openSync(path, 'r');
try {
// Perform operations
const buffer = Buffer.alloc(1024);
const bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0);
return buffer.subarray(0, bytesRead);
} finally {
fs.closeSync(fd); // Always close
}
}
// Use try-finally for exception safety
function writeToFile(path, data) {
const fd = fs.openSync(path, 'w');
try {
fs.writeSync(fd, data);
fs.fsyncSync(fd); // Ensure data is written
} finally {
fs.closeSync(fd);
}
}
// Handle async operations properly
function asyncFileRead(path, callback) {
fs.open(path, 'r', (err, fd) => {
if (err) return callback(err);
const buffer = Buffer.alloc(1024);
fs.read(fd, buffer, 0, buffer.length, 0, (readErr, bytesRead) => {
// Always close fd, even on error
fs.close(fd, (closeErr) => {
if (readErr) return callback(readErr);
if (closeErr) return callback(closeErr);
callback(null, buffer.subarray(0, bytesRead));
});
});
});
}Common file descriptor errors:
EBADF - Bad file descriptor (already closed or invalid)EMFILE - Too many open filesENOENT - File doesn't exist (openSync with 'r' flag)EEXIST - File exists (openSync with 'wx' flag)EISDIR - Is a directory (cannot open directory as file)EPERM - Permission deniedInstall with Tessl CLI
npx tessl i tessl/npm-metro-memory-fsdocs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10