$ gnpm install atomically
Read and write files atomically and reliably.
write-file-atomic, with some important enhancements on top, you can largely use this as a drop-in replacement.write-file-atomic, and it can be 10x faster, while being essentially just as safe, by using the fsyncWait option.write-file-atomic.write-file-atomic does, by default retrying some failed operations and handling some more errors.ENOSYS errors on chmod/chown operations are ignored.EINVAL/EPERM errors on chmod/chown operations, in POSIX systems where the user is not root, are ignored.EMFILE/ENFILE/EAGAIN/EBUSY/EACCESS/EACCES/EACCS/EPERM errors happening during necessary operations are caught and the operations are retried until they succeed or the timeout is reached.ENAMETOOLONG errors, both appening because of the final path or the temporary path, are attempted to be worked around by smartly truncating paths..tmp-[timestamp][randomness] suffix to destination paths:
tmp- part gives users a hint about the nature of these files, if they happen to see them.[timestamp] part consists of the 10 least significant digits of a milliseconds-precise timestamp, making it likely that if more than one of these files are kept on disk the user will see them in chronological order.[randomness] part consists of 6 random hex characters.chown: it allows you to specify custom group and user ids:
false the default ids are used.encoding: it allows you to specify the encoding of the file content:
utf8 is used when.fsync: it allows you to control whether the fsync syscall is triggered right after writing the file or not:
false the syscall won't be triggered.fsyncWait: it allows you to control whether the triggered fsync is waited or not:
false the syscall will still be triggered but not be waited.
fsync fails anyway.mode: it allows you to specify the mode for the file:
false then 0o666 is used.schedule: it's a function that returns a promise that resolves to a disposer function, basically it allows you to provide some custom queueing logic for the writing operation, allowing you to perhaps wire atomically with your app's main filesystem job scheduler:
schedule function is provided write operations will still be queued internally by the library too.timeout: it allows you to specify the amount of maximum milliseconds within which the library will retry some failed operations:
0 or -1 no failed operations will be retried.tmpCreate: it's a function that will be used to create the custom temporary file path in place of the default one:
ENAMETOOLONG errors.tmpCreated: it's a function that will be called with the newly created temporary file path.tmpPurge: it allows you to control whether the temporary file will be purged from the filesystem or not if the write fails:
false it will be kept on disk.npm install --save atomically
This is the shape of the optional options object:
type Disposer = () => void;
type ReadOptions = string | {
encoding?: string | null,
mode?: string | number | false,
timeout?: number
};
type WriteOptions = string | {
chown?: { gid: number, uid: number } | false,
encoding?: string | null,
fsync?: boolean,
fsyncWait?: boolean,
mode?: string | number | false,
schedule?: ( filePath: string ) => Promise<Disposer>,
timeout?: number,
tmpCreate?: ( filePath: string ) => string,
tmpCreated?: ( filePath: string ) => any,
tmpPurge?: boolean
};
This is the shape of the provided functions:
function readFile ( filePath: string, options?: ReadOptions ): Promise<Buffer | string>;
function readFileSync ( filePath: string, options?: ReadOptions ): Buffer | string;
function writeFile ( filePath: string, data: Buffer | string | undefined, options?: WriteOptions ): Promise<void>;
function writeFileSync ( filePath: string, data: Buffer | string | undefined, options?: WriteOptions ): void;
This is how to use the library:
import {readFile, readFileSync, writeFile, writeFileSync} from 'atomically';
// Asynchronous read with default option
const buffer = await readFile ( '/foo.txt' );
// Synchronous read assuming the encoding is "utf8"
const string = readFileSync ( '/foo.txt', 'utf8' );
// Asynchronous write with default options
await writeFile ( '/foo.txt', 'my_data' );
// Asynchronous write that doesn't prod the old file for a stat object at all
await writeFile ( '/foo.txt', 'my_data', { chown: false, mode: false } );
// 10x faster asynchronous write that's less resilient against imminent catastrophies
await writeFile ( '/foo.txt', 'my_data', { fsync: false } );
// 10x faster asynchronous write that's essentially still as resilient against imminent catastrophies
await writeFile ( '/foo.txt', 'my_data', { fsyncWait: false } );
// Asynchronous write with a custom schedule function
await writeFile ( '/foo.txt', 'my_data', {
schedule: filePath => {
return new Promise ( resolve => { // When this returned promise will resolve the write operation will begin
MyScheduler.schedule ( filePath, () => { // Hypothetical scheduler function that will eventually tell us to go on with this write operation
const disposer = () => {}; // Hypothetical function that contains eventual clean-up logic, it will be called after the write operation has been completed (successfully or not)
resolve ( disposer ); // Resolving the promise with a disposer, beginning the write operation
})
});
}
});
// Synchronous write with default options
writeFileSync ( '/foo.txt', 'my_data' );
MIT © Fabio Spampinato
Copyright 2013 - present © cnpmjs.org | Home |