Skip to content

Commit 5a896c0

Browse files
committed
Add fs utility to write data to a file
1 parent 2113ddb commit 5a896c0

File tree

20 files changed

+1377
-0
lines changed

20 files changed

+1377
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Write File
2+
3+
> Write data to a file.
4+
5+
<section class="usage">
6+
7+
## Usage
8+
9+
```javascript
10+
var writeFile = require( '@stdlib/fs/write-file' );
11+
```
12+
13+
#### writeFile( file, data, \[options,] clbk )
14+
15+
Asynchronously write `data` to a `file`.
16+
17+
```javascript
18+
var join = require( 'path' ).join;
19+
20+
var fpath = join( __dirname, 'examples', 'fixtures', 'file.txt' );
21+
22+
writeFile( fpath, 'beep boop\n', onWrite );
23+
24+
function onWrite( error, data ) {
25+
if ( error ) {
26+
throw error;
27+
}
28+
}
29+
```
30+
31+
The `data` argument may be either a `string` or a [`Buffer`][@stdlib/buffer/ctor].
32+
33+
```javascript
34+
var join = require( 'path' ).join;
35+
var string2buffer = require( '@stdlib/buffer/from-string' );
36+
37+
var fpath = join( __dirname, 'examples', 'fixtures', 'file.txt' );
38+
39+
writeFile( fpath, string2buffer( 'beep boop\n' ), onWrite );
40+
41+
function onWrite( error, data ) {
42+
if ( error ) {
43+
throw error;
44+
}
45+
}
46+
```
47+
48+
The function accepts the same `options` and has the same defaults as [`fs.writeFile()`][node-fs].
49+
50+
#### writeFile.sync( file, data\[, options] )
51+
52+
Synchronously writes `data` to a `file`.
53+
54+
```javascript
55+
var join = require( 'path' ).join;
56+
57+
var fpath = join( __dirname, 'examples', 'fixtures', 'file.txt' );
58+
59+
var err = writeFile.sync( fpath, 'beep boop\n' );
60+
if ( err instanceof Error ) {
61+
throw err;
62+
}
63+
```
64+
65+
The function accepts the same `options` and has the same defaults as [`fs.writeFileSync()`][node-fs].
66+
67+
</section>
68+
69+
<!-- /.usage -->
70+
71+
<section class="notes">
72+
73+
## Notes
74+
75+
- The difference between this `writeFile.sync` and [`fs.writeFileSync()`][node-fs] is that [`fs.writeFileSync()`][node-fs] will throw if an `error` is encountered (e.g., if given a non-existent directory path) and this API will return an `error`. Hence, the following anti-pattern
76+
77+
<!-- run-disable -->
78+
79+
```javascript
80+
var fs = require( 'fs' );
81+
82+
// Check for directory path existence to prevent an error being thrown...
83+
if ( fs.existsSync( '/path/to' ) ) {
84+
fs.writeFileSync( '/path/to/file.txt', 'beep boop\n' );
85+
}
86+
```
87+
88+
can be replaced by an approach which addresses existence via `error` handling.
89+
90+
<!-- run-disable -->
91+
92+
```javascript
93+
var writeFile = require( '@stdlib/fs/write-file' );
94+
95+
// Explicitly handle the error...
96+
var err = writeFile.sync( '/path/to/file.txt', 'beep boop\n' );
97+
if ( err instanceof Error ) {
98+
// You choose what to do...
99+
throw err;
100+
}
101+
```
102+
103+
</section>
104+
105+
<!-- /.notes -->
106+
107+
<section class="examples">
108+
109+
## Examples
110+
111+
<!-- eslint no-undef: "error" -->
112+
113+
```javascript
114+
var join = require( 'path' ).join;
115+
var writeFile = require( '@stdlib/fs/write-file' );
116+
117+
var fpath = join( __dirname, 'examples', 'fixtures', 'file.txt' );
118+
119+
// Synchronously write data to a file:
120+
var err = writeFile.sync( fpath, 'beep boop\n', 'utf8' );
121+
// returns null
122+
123+
console.log( err instanceof Error );
124+
// => false
125+
126+
// Asynchronously write data to a file:
127+
writeFile( fpath, 'beep boop\n', onWrite );
128+
129+
function onWrite( error ) {
130+
if ( error ) {
131+
console.error( 'Error: %s', error.message );
132+
}
133+
console.log( 'Success!' );
134+
}
135+
```
136+
137+
</section>
138+
139+
<!-- /.examples -->
140+
141+
* * *
142+
143+
<section class="cli">
144+
145+
## CLI
146+
147+
<section class="usage">
148+
149+
### Usage
150+
151+
```text
152+
Usage: writefile [options] <filepath>
153+
154+
Options:
155+
156+
-h, --help Print this message.
157+
-V, --version Print the package version.
158+
--enc, --encoding encoding Encoding. Default: 'utf8'.
159+
--flag flag Flag. Default: 'r'.
160+
--mode mode Mode. Default: 0o666.
161+
```
162+
163+
</section>
164+
165+
<!-- /.usage -->
166+
167+
<section class="notes">
168+
169+
### Notes
170+
171+
- Relative output file paths are resolved relative to the current working directory.
172+
- Errors are written to `stderr`.
173+
- File contents should be provided over `stdin` as part of a [standard stream][standard-stream] pipeline.
174+
175+
</section>
176+
177+
<!-- /.notes -->
178+
179+
<section class="examples">
180+
181+
### Examples
182+
183+
```bash
184+
$ printf 'beep boop\n' | writefile ./examples/fixtures/file.txt
185+
```
186+
187+
</section>
188+
189+
<!-- /.examples -->
190+
191+
</section>
192+
193+
<!-- /.cli -->
194+
195+
<section class="links">
196+
197+
[node-fs]: https://nodejs.org/api/fs.html
198+
199+
[@stdlib/buffer/ctor]: https://github.com/stdlib-js/stdlib
200+
201+
[standard-stream]: http://en.wikipedia.org/wiki/Pipeline_%28Unix%29
202+
203+
</section>
204+
205+
<!-- /.links -->
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
// MODULES //
4+
5+
var join = require( 'path' ).join;
6+
var bench = require( '@stdlib/bench' );
7+
var readFile = require( '@stdlib/fs/read-file' ).sync;
8+
var pkg = require( './../package.json' ).name;
9+
var writeFile = require( './../lib' );
10+
11+
12+
// FIXTURES //
13+
14+
var FILE = join( __dirname, 'fixtures', 'file.txt' );
15+
var DATA = readFile( FILE );
16+
17+
18+
// MAIN //
19+
20+
bench( pkg, function benchmark( b ) {
21+
var i;
22+
23+
i = 0;
24+
b.tic();
25+
26+
return next();
27+
28+
function next() {
29+
i += 1;
30+
if ( i <= b.iterations ) {
31+
return writeFile( FILE, DATA, done );
32+
}
33+
b.toc();
34+
b.pass( 'benchmark finished' );
35+
b.end();
36+
}
37+
38+
function done( error ) {
39+
if ( error ) {
40+
b.fail( error.message );
41+
}
42+
next();
43+
}
44+
});
45+
46+
bench( pkg+':sync', function benchmark( b ) {
47+
var out;
48+
var i;
49+
50+
b.tic();
51+
for ( i = 0; i < b.iterations; i++ ) {
52+
out = writeFile.sync( FILE, DATA );
53+
if ( out instanceof Error ) {
54+
b.fail( out.message );
55+
}
56+
}
57+
b.toc();
58+
if ( out instanceof Error ) {
59+
b.fail( out.message );
60+
}
61+
b.pass( 'benchmark finished' );
62+
b.end();
63+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
beep boop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env node
2+
3+
'use strict';
4+
5+
// MODULES //
6+
7+
var resolve = require( 'path' ).resolve;
8+
var readFileSync = require( '@stdlib/fs/read-file' ).sync;
9+
var CLI = require( '@stdlib/tools/cli' );
10+
var stdin = require( '@stdlib/utils/read-stdin' );
11+
var cwd = require( '@stdlib/utils/cwd' );
12+
var writeFile = require( './../lib' );
13+
14+
15+
// FUNCTIONS //
16+
17+
/**
18+
* Callback invoked upon writing a file.
19+
*
20+
* @private
21+
* @param {Error} [error] - error object
22+
* @returns {void}
23+
*/
24+
function onWrite( error ) {
25+
if ( error ) {
26+
process.exitCode = 1;
27+
return console.error( 'Error: %s', error.message ); // eslint-disable-line no-console
28+
}
29+
} // end FUNCTION onWrite()
30+
31+
32+
// MAIN //
33+
34+
/**
35+
* Main execution sequence.
36+
*
37+
* @private
38+
* @returns {void}
39+
*/
40+
function main() {
41+
var flags;
42+
var fpath;
43+
var args;
44+
var opts;
45+
var cli;
46+
47+
// Create a command-line interface:
48+
cli = new CLI({
49+
'pkg': require( './../package.json' ),
50+
'options': require( './../etc/cli_opts.json' ),
51+
'help': readFileSync( resolve( __dirname, '..', 'docs', 'usage.txt' ), {
52+
'encoding': 'utf8'
53+
})
54+
});
55+
56+
// Get any provided command-line arguments:
57+
args = cli.args();
58+
59+
// Get any provided command-line flags:
60+
flags = cli.flags();
61+
62+
opts = {};
63+
if ( flags.encoding ) {
64+
opts.encoding = flags.encoding;
65+
}
66+
if ( flags.flag ) {
67+
opts.flag = flags.flag;
68+
}
69+
if ( flags.mode ) {
70+
opts.mode = parseInt( flags.mode, 8 );
71+
}
72+
fpath = resolve( cwd(), args[ 0 ] );
73+
74+
// Gather data from `stdin`...
75+
return stdin( onRead );
76+
77+
/**
78+
* Callback invoked upon reading from `stdin`.
79+
*
80+
* @private
81+
* @param {(Error|null)} error - error object
82+
* @param {Buffer} data - data
83+
* @returns {void}
84+
*/
85+
function onRead( error, data ) {
86+
if ( error ) {
87+
process.exitCode = 1;
88+
return console.error( 'Error: %s', error.message ); // eslint-disable-line no-console
89+
}
90+
writeFile( fpath, data, opts, onWrite );
91+
} // end FUNCTION onRead()
92+
} // end FUNCTION main()
93+
94+
main();

0 commit comments

Comments
 (0)