>[success] # 文件的寫入
| API名稱 | 描述 | 優點 | 缺點 |
| --- | --- | --- | --- |
| fs.writeFile() | 寫入文件內容,如果文件不存在則創建文件,如果文件已存在則覆蓋文件內容 | 簡單易用,支持回調函數和Promise兩種寫法 | 無法指定寫入文件的位置,無法實現數據追加 |
| fs.writeFileSync() | 同步地寫入文件內容,如果文件不存在則創建文件,如果文件已存在則覆蓋文件內容 | 簡單易用,支持同步寫法 | 阻塞IO操作,不適用于高并發場景 |
| fs.promises.writeFile() | 使用Promise對象寫入文件內容,如果文件不存在則創建文件,如果文件已存在則覆蓋文件內容 | 支持Promise鏈式調用,代碼可讀性好 | 無法指定寫入文件的位置,無法實現數據追加 |
| fs.appendFile() | 將數據追加到文件中,如果文件不存在則創建文件 | 可以實現數據追加,支持回調函數和Promise兩種寫法 | 無法指定寫入文件的位置,每次寫入都需要遍歷整個文件 |
| fs.appendFileSync() | 同步地將數據追加到文件中,如果文件不存在則創建文件 | 可以實現數據追加,支持同步寫法 | 阻塞IO操作,不適用于高并發場景 |
| fs.promises.appendFile() | 使用Promise對象將數據追加到文件中,如果文件不存在則創建文件 | 可以實現數據追加,支持Promise鏈式調用,代碼可讀性好 | 無法指定寫入文件的位置,每次寫入都需要遍歷整個文件 |
| fs.createWriteStream() | 創建一個可寫流來寫入數據到文件 | 可以指定寫入文件的位置和實現數據追加,適用于大文件寫入和高并發場景 | 適用于大文件寫入和高并發場景,使用比較繁瑣,需要多次調用該方法才能完成完整的寫入操作 |
| fs.write() | 向文件中寫入數據,可以指定寫入文件的位置和實現數據追加,適用于大文件寫入和高并發場景 | 可以指定寫入文件的位置和實現數據追加,適用于大文件寫入和高并發場景 | 使用比較繁瑣,需要多次調用該方法才能完成完整的寫入操作 |
| fs.writeSync() | 同步地向文件中寫入數據,可以指定寫入文件的位置和實現數據追加,適用于大文件寫入和高并發場景 | 可以指定寫入文件的位置和實現數據追加,適用于大文件寫入和高并發場景 | 阻塞IO操作,不適用 |
>[danger] ### fs.writeFile(data, options)
1. `fs.writeFile()`方法用于將數據寫入指定的文件中。如果文件不存在,則會創建一個新文件。如果文件已經存在,則它將被覆蓋。
>[danger] ##### api
1. `options.signal`是一個可選的參數,用于傳遞`AbortSignal`對象,用于在讀取文件時中止讀取操作。`AbortSignal`是一個可以用于終止某些操作的信號對象。當調用`AbortSignal.abort()`函數時,可以向一個或多個正在進行的異步操作發送一個中止信號以取消操作。
2. 雖然 `fs.writeFile()` api 寫入文件內容,如果文件不存在則創建文件,如果文件已存在則覆蓋文件內容,因為默認flag 為`w`,如果配置例如`a` 即可繼續在末尾追加內容
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| file | string `|` Buffer `|` URL `|` integer | 文件名或文件描述符 |
| data | string `|` Buffer `|` TypedArray `|` DataView `|` Object | 要寫入文件的數據 |
| options | Object `|` string | 可選的參數對象或字符串 |
| options.encoding | string `|` null | 指定寫入文件時使用的字符編碼,默認為 'utf8' |
| options.mode | integer | 指定文件的權限,默認為 0o666 |
| options.flag | string | 指定打開文件時的行為,默認為 'w' |
| options.signal | AbortSignal | 允許中止正在進行的寫入文件 |
| options.callback | Function | 寫入文件完成后的回調函數 |
>[danger] ##### 案例
~~~
const fs = require('fs')
// 寫入文件 如果文件存在會覆蓋
fs.writeFile('./test.txt', 'hello world', (err) => {
if (err) {
throw err
}
console.log('文件寫入成功')
})
// 寫入文件使用其他參數,使用wx+ 文件存在會報錯
fs.writeFile(
'./test1.txt',
'hello world11111111111111111111',
{ flag: 'wx+' },
(err) => {
if (err) {
console.log(err)
}
console.log('文件寫入成功')
}
)
~~~
* 使用signal 組織文件寫入
~~~
const fs = require('fs')
const controller = new AbortController()
const signal = controller.signal
const options = { signal }
// 寫入文件 如果文件存在會覆蓋
fs.writeFile('./test.txt', 'hello world', options, (err) => {
if (err) {
if (err.code === 'ABORT_ERR') {
console.log('文件寫入被中斷')
} else {
console.log('文件寫入失敗')
}
} else {
console.log('文件寫入成功')
}
})
// 1秒后中斷文件寫入
setTimeout(() => {
controller.abort()
}, 1000)
~~~
>[danger] ### fsPromises.writeFile(file, data[, options])
1. `fsPromises.writeFile()` 函數用于異步地將數據寫入文件中,當我們調用 `fsPromises.writeFile() `方法時,Node.js 會異步地打開一個文件,并將數據寫入該文件
2. 如果指定的文件路徑不存在,則` fsPromises.writeFile() `方法會自動創建該文件并將數據寫入;如果文件已存在,則 `fsPromises.writeFile() `方法會覆蓋原有的內容。需要注意的是,由于 `writeFile() `屬于一個異步方法,所以在寫入文件完成之前,程序會繼續執行下去,不會等待` writeFile() `方法的返回結果。如果需要等待 writeFile() 方法執行完畢后再進行其他操作,可以使用 `then()` 或 `await `關鍵字來等待方法的返回結果。最后,`fsPromises.writeFile() `方法返回一個 `Promise `對象,可以通過 `then() 和 catch() `方法來處理寫入文件成功或失敗的情況
>[danger] ##### api
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| file | string \| Buffer \| URL \| FileHandle | 要寫入的文件名或 FileHandle。 |
| data | string \| Buffer \| TypedArray \| DataView \| AsyncIterable \| Iterable \| Stream | 要寫入的數據。可以是字符串、Buffer、TypedArray、DataView、AsyncIterable、Iterable 或 Stream。 |
| options | Object \| string | 可選的參數對象或字符串。如果是字符串,則會被解析為 encoding。可選的屬性有: |
| options.encoding | string | null | 要使用的字符編碼。默認為 'utf8'。 |
| options.mode | integer | 文件的權限設置,默認為 0o666(即讀寫所有人)。 |
| options.flag | string | 文件的打開標志,默認為 'w'(如果文件不存在則創建文件;如果文件已存在則截斷文件)。 |
| options.signal | AbortSignal | 允許中止正在進行的寫入文件操作。 |
>[danger] ##### 案例
~~~
const fsPromises = require('fs').promises
fsPromises
.writeFile('test.txt', 'Hello World', { flag: 'a' })
.then(() => {
console.log('文件寫入成功')
})
.catch((err) => {
console.log(err)
})
~~~
* signal終止文件
~~~
const fsPromises = require('fs').promises
const controller = new AbortController()
const signal = controller.signal
const options = { signal }
// 寫入文件
function writeFile() {
try {
// fsPromises.writeFile('./test.txt', 'hello world', 'utf8')
fsPromises.writeFile('./test.txt', 'hello world', options)
} catch (error) {
console.log(error)
if (error.name === 'AbortError') {
console.log('寫入終止')
}
}
}
writeFile()
// 終止寫入
setTimeout(() => {
controller.abort()
}, 1000)
~~~
>[danger] ### fs.writeFileSync(file, data[, options])
1. `fs.writeFileSync(file, data[, options])`是 Node.js 中的文件系統模塊(`fs`)提供的同步寫文件方法。它用于將指定的數據寫入指定的文件。
2. 該方法會將指定數據寫入指定文件中,并返回 undefined。如果文件不存在,則該方法會創建文件。如果文件已存在,則該方法會覆蓋原有文件內容,并寫入新的數據。
3. ,`fs.writeFileSync()`方法是同步的,會阻塞 Node.js 事件循環,直到文件寫入完成。因此,在處理大量數據或需要頻繁寫入文件的情況下,建議使用異步寫入方法`fs.writeFile()`,以避免阻塞事件循環。
>[danger] ##### api
| 參數 | 類型 | 描述 | 默認值 |
| --- | --- | --- | --- |
| `file` | `string`\|`Buffer`\|`URL`\|`integer` | 文件名或文件描述符 | |
| `data` | `string`\|`Buffer`\|`TypedArray`\|`DataView`\|`Object` | 要寫入文件的數據 | |
| `options` | `Object`\|`string` | 可選參數,可以指定寫入的編碼格式和文件寫入模式等 | |
| `options.encoding` | `string`\|`null` | 指定編碼格式 | `'utf8'` |
| `options.mode` | `integer` | 指定文件寫入模式 | `0o666` |
| `options.flag` | `string` | 指定文件寫入標志 | `'w'` |
>[danger] ##### 案例
~~~
const fs = require('fs')
try {
fs.writeFileSync('test.txt', 'Hello World!')
} catch (err) {
console.log(err)
}
fs.writeFileSync('test.txt', '歡迎', { flag: 'a+' })
~~~
>[danger] ### fsPromises.writeFile(file, data\[, options\])
`fsPromises.writeFile()`是 Node.js 的一個內置函數,它用于將數據寫入到指定的文件中。這個函數是通過 Promise 的方式實現的,因此它會返回一個 Promise 對象
>[danger] ##### api
| 參數名 | 類型 | 描述 | 默認值 |
| --- | --- | --- | --- |
| `file` | string \| Buffer \| URL \| FileHandle | 要寫入的文件的路徑或文件句柄 | 無 |
| `data` | string \| Buffer \| TypedArray \| DataView \| Object \| AsyncIterable \| Iterable \| Stream | 要寫入的數據,可以是字符串、Buffer、TypedArray、DataView、Object、AsyncIterable、Iterable 或 Stream 類型 | 無 |
| `options` | Object \| string | 可選參數,一個對象,可以指定寫入文件時的選項,比如編碼方式、文件模式等。如果是字符串,則表示編碼方式,例如`'utf8'`。 | `{ encoding: 'utf8', mode: 0o666, flag: 'w' }` |
| `options.encoding` | string \| null | 指定要使用的編碼方式。如果沒有指定,則默認使用`'utf8'`編碼。如果指定為`null`,則會將數據寫入文件中,而不進行編碼。 | `'utf8'` |
| `options.mode` | integer | 指定在創建文件時要設置的權限位掩碼(文件模式)。默認值為`0o666`,表示允許讀寫文件。 | `0o666` |
| `options.flag` | string | 指定打開文件時要使用的標志。默認值為`'w'`,表示要以寫入模式打開文件。 | `'w'` |
| `options.signal` | AbortSignal | 允許中止正在進行的寫入文件操作。 | 無 |
>[danger] ##### 案例
~~~
const fs = require('fs')
const fd = fs.openSync('test.txt', 'w')
fs.promises.writeFile('./a.txt', 'Hello World').then(() => console.log('Done'))
~~~
>[danger] ### fs.appendFile 系列
1. 如果你將`fs.writeFile()`方法的`flag`參數設置為`a`,那么它就會以追加的模式寫入文件,與`fs.appendFile()`方法的行為相同。因此,它們可以被認為是等效的,因此直接參考`fs.writeFile()`即可
>[danger] ### fs.write(fd, buffer[, offset[, length[, position]]], callback) / fs.write(fd, string[, position[, encoding]], callback)
1. 使用該方法需要先通過`fs.open()`方法打開文件獲取文件描述符。該方法適用于大文件寫入和高并發場景,可以指定寫入文件的位置和實現數據追加。但是使用比較繁瑣,需要多次調用該方法才能完成完整的寫入操作。同時,由于需要手動管理文件指針,使用不當可能會導致數據覆蓋或丟失,需要謹慎使用。
2. 注意要**手動關閉文件**
| 優點 | 缺點 |
| --- | --- |
| 可以指定寫入文件的位置和實現數據追加 | 使用比較繁瑣,需要多次調用該方法才能完成完整的寫入操作 |
| 能夠精準控制寫入的緩沖區和字節數,可以提高寫入效率和靈活性 | 需要手動管理文件指針,使用不當可能會導致數據覆蓋或丟失,需要謹慎使用 |
| 適用于大文件寫入和高并發場景 | 不支持 Promise 語法,只能使用回調函數來處理寫入完成后的操作 |
>[danger] ##### api
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| fd | integer | 打開的文件描述符 |
| buffer | Buffer / TypedArray / DataView | 寫入的緩沖區 |
| offset | integer(可選) | 緩沖區中開始寫入的偏移量,默認為 0 |
| length | integer(可選) | 寫入的字節數,默認為緩沖區的長度 |
| position | integer(可選) | 文件中開始寫入的位置,默認為當前文件指針的位置 |
| callback | Function | 寫入操作完成后的回調函數,帶有一個錯誤參數和寫入的字節數參數 |
| callback err | Error | 錯誤對象,如果寫入過程中出現錯誤則會被賦值 |
| callback bytesWritten | integer | 寫入的字節數 |
| callback buffer | Buffer / TypedArray / DataView | 與寫入操作關聯的緩沖區,在回調函數中可以使用 |
* fs.write(fd, string\[, position\[, encoding\]\], callback)
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| fd | integer | 打開的文件描述符 |
| string | string / Buffer | 寫入的數據,可以為字符串或 Buffer 對象 |
| position | integer(可選) | 文件中開始寫入的位置,默認為當前文件指針的位置 |
| encoding | string(可選) | 字符串的編碼格式,默認為 'utf8' |
| callback | Function | 寫入操作完成后的回調函數,帶有一個錯誤參數和寫入的字節數參數 |
| err | Error | 錯誤對象,如果寫入過程中出現錯誤則會被賦值 |
>[danger] ##### 案例
~~~
const fs = require('fs')
// 打開文件
fs.open('file.txt', 'a', (err, fd) => {
if (err) throw err
// 寫入緩沖區
const buffer = Buffer.from('Hello World!', 'utf-8')
// 寫入數據
fs.write(fd, buffer, 0, buffer.length, null, (err, bytesWritten) => {
if (err) throw err
console.log(`${bytesWritten} 字節已被寫入文件`)
})
// 關閉文件
fs.close(fd, (err) => {
if (err) throw err
})
})
~~~
* fs.write(fd, string\[, position\[, encoding\]\], callback)
~~~
const fs = require('fs')
const fd = fs.openSync('test.txt', 'w')
fs.writeSync(fd, 'hello world', 0, 'utf-8', (err) => {
if (err) console.log('err')
else console.log('write success')
})
fs.closeSync(fd)
~~~
>[danger] ### fs.writeSync(fd, buffer[, offset[, length[, position]]]) / fs.writeSync(fd, string[, position[, encoding]])
1. 是Node.js中文件系統模塊(fs)提供的同步寫入文件的API方法。它的作用是將指定的緩沖區(buffer)中的數據寫入到文件描述符(fd)所指向的文件中。
2. 返回值是一個整數值,表示實際寫入文件的字節數
3. 需要手動關閉
4. 注意事項:
* 使用`fs.writeSync()`方法時會阻塞進程,直到數據被寫入到文件中。因此,建議在需要同步寫入文件時使用該方法,而不是異步寫入文件的方法`fs.write()`。
* 在使用`fs.writeSync()`方法時,要確保文件描述符是有效的,并且緩沖區中的數據不會超出文件的大小限制。
* 在寫入數據到文件時,要注意文件的打開方式和文件的訪問權限,否則可能會導致寫入失敗或寫入的數據被其他進程覆蓋。
>[danger] ##### api
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| `fd` | `integer` | 文件描述符,它是由`fs.open()`方法返回的整數值。 |
| `buffer` | `Buffer`|`TypedArray`|`DataView`|`string`|`Object` | 要寫入文件的緩沖區,可以是Buffer對象或Uint8Array類型。 |
| `offset` | `integer`(可選) | 緩沖區中的偏移量,指定從緩沖區的哪個位置開始寫入數據到文件。默認值為0。 |
| `length` | `integer`(可選) | 要寫入的字節數,指定從緩沖區中寫入多少字節的數據到文件。默認值為緩沖區的長度。 |
| `position` | `integer`(可選) | 指定從文件的哪個位置開始寫入數據,如果省略該參數,則從文件的當前位置開始寫入數據。 |
* fs.writeSync(fd, string\[, position\[, encoding\]\]
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| fd | integer | 打開的文件描述符 |
| string | string / Buffer /TypedArray/DataView/ Object | 寫入的數據,可以為字符串、Buffer 對象、TypedArray、DataView 或 Object 對象 |
| position | integer(可選) | 文件中開始寫入的位置,默認為當前文件指針的位置 |
| encoding | string(可選) | 字符串的編碼格式 |
| 返回值 | integer | 寫入的字節數 |
>[danger] ##### 案例
~~~
const fs = require('fs')
const fd = fs.openSync('test.txt', 'w')
try {
const buf = Buffer.from('Hello World', 'utf8')
fs.writeSync(fd, buf, 0, buf.length, 0)
fs.closeSync(fd)
} catch (e) {
console.log(e)
}
~~~
* fs.writeSync(fd, string[, position[, encoding]]
~~~
const fs = require('fs')
const fd = fs.openSync('test.txt', 'w')
try {
fs.writeSync(fd, 'Hello World', 0, 'utf-8')
fs.closeSync(fd)
} catch (e) {
console.log(e)
}
~~~
>[danger] ### fs.createWriteStream(path[, options])
1. `fs.createWriteStream()`是 Node.js 文件系統模塊中的一個函數,用于創建一個可寫流,將數據寫入到指定的文件中。它的參數包括路徑和選項,其中路徑是需要寫入的文件的完整路徑,選項包括各種可選參數,如編碼方式、寫入模式、緩沖區大小等等。`fs.createWriteStream()`返回一個可寫流對象,你可以使用它的`write()`方法來將數據寫入文件中,使用`end()`方法來結束寫入操作。在寫入完成后,可寫流對象會自動關閉。
>[danger] ##### api
| 參數 | 類型 | 描述 | 默認值 |
| --- | --- | --- | --- |
| path | string|Buffer|URL | 文件的路徑 | 無 |
| options | string|Object | 可選的配置項 | 無 |
| options.flags | string | 文件打開的標志,參考[文件系統 flags](https://nodejs.org/docs/latest-v16.x/api/fs.html#fs_file_system_flags) | `'w'` |
| options.encoding | string | 寫入的編碼方式 | `'utf8'` |
| options.fd | integer|FileHandle | 文件描述符或文件句柄 | `null` |
| options.mode | integer | 創建文件的權限 | `0o666` |
| options.autoClose | boolean | 是否自動關閉文件 | `true` |
| options.emitClose | boolean | 是否在關閉文件時發送`close`事件 | `true` |
| options.start | integer | 寫入文件的起始位置 | `0` |
| options.fs | Object|null | 文件系統模塊 | `null` |
>[danger] ##### 案例
~~~
const fs = require('fs');
const writeStream = fs.createWriteStream('output.txt', {
flags: 'a', // 追加模式
encoding: 'utf8',
mode: 0o666,
autoClose: true,
start: 0,
highWaterMark: 64 * 1024 // 64KB 緩沖區
});
writeStream.write('Hello, world!', 'utf8', () => {
console.log('數據寫入成功!');
});
writeStream.end(() => {
console.log('文件寫入完成!');
});
~~~
- 基礎
- 什么是Node.js
- 理解 I/O 模型
- 理解node 中 I/O
- 對比node 和java 使用場景
- node 模塊管理
- 內置模塊 -- buffer
- 內置模塊 -- fs
- fs -- 文件描述符
- fs -- 打開文件 api
- fs -- 文件讀取 api
- fs -- 文件寫入 api
- fs -- 創建目錄 api
- fs -- 讀取文件目錄結構 api
- fs -- 文件狀態(信息) api
- fs -- 刪除文件/目錄 api
- fs -- 重命名 api
- fs -- 復制文件 api
- 內置模塊 -- events
- 內置模塊 -- stream
- 可讀流 -- Readable
- 可寫流 -- Writable
- Duplex
- Transform
- 內置模塊 -- http
- http -- 從客戶端發起
- http -- 從服務端發起
- 內置模塊 -- url
- 網絡開發