@@ -10,6 +10,7 @@ const kReadFileMaxChunkSize = 2 ** 14;
10
10
const kWriteFileMaxChunkSize = 2 ** 14 ;
11
11
12
12
const {
13
+ ArrayIsArray,
13
14
ArrayPrototypePush,
14
15
Error,
15
16
MathMax,
@@ -21,7 +22,9 @@ const {
21
22
PromiseResolve,
22
23
SafeArrayIterator,
23
24
Symbol,
24
- Uint8Array,
25
+ SymbolAsyncIterator,
26
+ SymbolIterator,
27
+ Uint8Array
25
28
} = primordials ;
26
29
27
30
const {
@@ -41,7 +44,7 @@ const {
41
44
ERR_INVALID_ARG_VALUE ,
42
45
ERR_METHOD_NOT_IMPLEMENTED ,
43
46
} = codes ;
44
- const { isArrayBufferView } = require ( 'internal/util/types' ) ;
47
+ const { isArrayBufferView, isTypedArray } = require ( 'internal/util/types' ) ;
45
48
const { rimrafPromises } = require ( 'internal/fs/rimraf' ) ;
46
49
const {
47
50
copyObject,
@@ -663,19 +666,55 @@ async function writeFile(path, data, options) {
663
666
options = getOptions ( options , { encoding : 'utf8' , mode : 0o666 , flag : 'w' } ) ;
664
667
const flag = options . flag || 'w' ;
665
668
666
- if ( ! isArrayBufferView ( data ) ) {
667
- validateStringAfterArrayBufferView ( data , 'data' ) ;
668
- data = Buffer . from ( data , options . encoding || 'utf8' ) ;
669
- }
669
+ if ( isIterable ( data ) ) {
670
+ if ( options . signal ?. aborted ) {
671
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
672
+ }
673
+ const fd = await open ( path , flag , options . mode ) ;
674
+ try {
675
+ if ( options . signal ?. aborted ) {
676
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
677
+ }
678
+ for await ( const buf of data ) {
679
+ if ( options . signal ?. aborted ) {
680
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
681
+ }
682
+ await fd . write ( buf ) ;
683
+ if ( options . signal ?. aborted ) {
684
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
685
+ }
686
+ }
687
+ } finally {
688
+ await fd . close ( ) ;
689
+ }
690
+ } else {
691
+ if ( ! isArrayBufferView ( data ) ) {
692
+ validateStringAfterArrayBufferView ( data , 'data' ) ;
693
+ data = Buffer . from ( data , options . encoding || 'utf8' ) ;
694
+ }
670
695
671
- if ( path instanceof FileHandle )
672
- return writeFileHandle ( path , data , options . signal ) ;
696
+ if ( path instanceof FileHandle ) {
697
+ return writeFileHandle ( path , data , options . signal ) ;
698
+ }
673
699
674
- const fd = await open ( path , flag , options . mode ) ;
675
- if ( options . signal ?. aborted ) {
676
- throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
700
+ const fd = await open ( path , flag , options . mode ) ;
701
+ if ( options . signal ?. aborted ) {
702
+ throw lazyDOMException ( 'The operation was aborted' , 'AbortError' ) ;
703
+ }
704
+ return PromisePrototypeFinally ( writeFileHandle ( fd , data ) , fd . close ) ;
677
705
}
678
- return PromisePrototypeFinally ( writeFileHandle ( fd , data ) , fd . close ) ;
706
+ }
707
+
708
+ function isIterable ( obj ) {
709
+ if ( obj == null ) {
710
+ return false ;
711
+ }
712
+
713
+ return SymbolAsyncIterator in obj || (
714
+ SymbolIterator in obj &&
715
+ typeof obj !== 'string' &&
716
+ ! ArrayIsArray ( obj ) &&
717
+ ! isTypedArray ( obj ) ) ;
679
718
}
680
719
681
720
async function appendFile ( path , data , options ) {
0 commit comments