天天看點

fs - 檔案系統

​<code>​ fs​</code>​ 子產品提供了一些 API,用于以一種類似标準 POSIX 函數的方式與檔案系統進行互動。

用法如下:

<col>

​<code>​異步形式的最後一個參數都是完成時回調函數。 傳給回調函數的參數取決于具體方法,但回調函數的第一個參數都會保留給異常。 如果操作成功完成,則第一個參數會是 null 或 undefined。​</code>​

當使用同步操作時,任何異常都會被立即抛出,可以使用 ​<code>​try​</code>​/​<code>​catch​</code>​ 來處理異常,或讓異常向上冒泡。

大部分 ​<code>​fs​</code>​ 操作接受字元串、​<code>​Buffer​</code>​、或使用 ​<code>​file:​</code>​ 協定的 ​<code>​URL​</code>​ 對象作為檔案路徑。

字元串形式的路徑會被解釋為表示絕對路徑或相對路徑的 UTF-8 字元序列。 相對路徑會相對于 ​<code>​process.cwd()​</code>​ 定義的目前工作目錄進行處理。

使用絕對路徑的例子:

使用 ​<code>​Buffer​</code>​ 定義的路徑主要用于将檔案路徑處理為 opaque 位元組序列的特定 POSIX 作業系統。 在這種系統上,一個檔案路徑可能包含使用多種字元編碼的子序列。 與字元串路徑一樣,​<code>​Buffer​</code>​ 路徑也可以是相對的或絕對的。

對于大多數 ​<code>​fs​</code>​ 子產品的函數,​<code>​path​</code>​ 或 ​<code>​filename​</code>​ 參數可以傳入 WHATWG ​​URL​​ 對象。 隻支援使用 ​<code>​file:​</code>​ 協定的 ​​URL​​ 對象。

​<code>​file:​</code>​ URL 必須是絕對路徑。

在 POSIX 系統,核心為所有程序維護着一張目前打開着的檔案與資源的表格。 每個打開的檔案都會配置設定一個名為檔案描述符的數值辨別。 在系統層,所有檔案系統操作使用這些檔案描述符來識别與追蹤每個特定的檔案。 Window 系統使用了一個不同但概念類似的機制來追蹤資源。 為友善使用者,Node.js 抽象了不同作業系統間的差異,為所有打開的檔案配置設定了數值的檔案描述符。

​<code>​fs.open()​</code>​ 方法用于配置設定一個新的檔案描述符。 一旦配置設定了,檔案描述符可用于讀取資料、寫入資料、或檢視檔案資訊。

​<code>​注意:大多數作業系統會限制打開的檔案描述符的數量,是以當操作完成時需關閉描述符。 如果不這樣做會導緻記憶體洩漏,最終造成應用奔潰。​</code>​

略過。

​<code>​fs.Stats​</code>​ 對象提供了一個檔案的資訊。

從 ​<code>​fs.stat()​</code>​、​<code>​fs.lstat()​</code>​ 和 ​<code>​fs.fstat()​</code>​ 及其同步版本傳回的對象都是該類型。

傳回的資訊包含如下:

stats.isDirectory()      如果 ​<code>​fs.Stats​</code>​ 對象表示一個檔案系統目錄,則傳回 ​<code>​true​</code>​ 。

stats.isFile()      如果 ​<code>​fs.Stats​</code>​ 對象表示一個普通檔案,則傳回 ​<code>​true​</code>​ 。

stats.size    檔案的位元組大小。

​<code>​file​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt; | &lt;number&gt; 檔案名或檔案描述符

​<code>​data​</code>​&lt;string&gt; | &lt;Buffer&gt;

​<code>​options​</code>​&lt;Object&gt; | &lt;string&gt;

​<code>​encoding​</code>​&lt;string&gt; | &lt;null&gt; 預設為 ​<code>​'utf8'​</code>​

​<code>​mode​</code>​&lt;integer&gt; 預設為 ​<code>​0o666​</code>​

​<code>​flag​</code>​&lt;string&gt; 預設為 ​<code>​'a'​</code>​

​<code>​callback​</code>​&lt;Function&gt;

​<code>​err​</code>​&lt;Error&gt;

異步地追加資料到一個檔案,如果檔案不存在則建立檔案。 ​<code>​data​</code>​ 可以是一個字元串或 ​<code>​Buffer​</code>​。

如果 ​<code>​options​</code>​ 是一個字元串,則它指定了字元編碼。

​<code>​file​</code>​ 可能是一個被打開用來追加資料的數字檔案描述符(通過 ​<code>​fs.open()​</code>​ 或者 ​<code>​fs.openSync()​</code>​)。這樣的檔案描述符将不會被自動關閉。

fs.chmod(path, mode, callback)   異步地改變檔案的權限。 完成回調隻有一個可能的異常參數。

​<code>​path​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt;

​<code>​mode​</code>​ &lt;integer&gt;

<code>​callback​</code>​ &lt;Function&gt;

​<code>​err​</code>​ &lt;Error&gt;

​<code>​mode​</code>​ 參數會在 ​<code>​fs.chmod()​</code>​ 和 ​<code>​fs.chmodSync()​</code>​方法中用到,它是用下面的常量進行邏輯或(logical OR)操作後的數字掩碼:

Constant

Octal

Description

​<code>​fs.constants.S_IRUSR​</code>​

​<code>​0o400​</code>​

read by owner

​<code>​fs.constants.S_IWUSR​</code>​

​<code>​0o200​</code>​

write by owner

​<code>​fs.constants.S_IXUSR​</code>​

​<code>​0o100​</code>​

execute/search by owner

​<code>​fs.constants.S_IRGRP​</code>​

​<code>​0o40​</code>​

read by group

​<code>​fs.constants.S_IWGRP​</code>​

​<code>​0o20​</code>​

write by group

​<code>​fs.constants.S_IXGRP​</code>​

​<code>​0o10​</code>​

execute/search by group

​<code>​fs.constants.S_IROTH​</code>​

​<code>​0o4​</code>​

read by others

​<code>​fs.constants.S_IWOTH​</code>​

​<code>​0o2​</code>​

write by others

​<code>​fs.constants.S_IXOTH​</code>​

​<code>​0o1​</code>​

execute/search by others

一個構造 ​<code>​mode​</code>​ 的更簡單的方式是使用3位八進制串(比如,765)。最左側的數字(例中的7)代表了檔案所有者的權限。中間一位(例中的6)代表了組的權限。最右側的數字(例中的5)代表其他人的權限。 A

Number

​<code>​7​</code>​

read, write, and execute

​<code>​6​</code>​

read and write

​<code>​5​</code>​

read and execute

​<code>​4​</code>​

read only

​<code>​3​</code>​

write and execute

​<code>​2​</code>​

write only

​<code>​1​</code>​

execute only

​<code>​0​</code>​

no permission

舉個例子,八進制值 ​<code>​0o765​</code>​ 表示:

檔案所有者可以進行讀、寫和執行。

檔案所屬組可以讀和寫。

其他人可以對檔案進行讀和執行。

​<code>​fd​</code>​ &lt;integer&gt;

異步的 ​<code>​close(2)​</code>​。 完成回調隻有一個可能的異常參數。

​<code>​src​</code>​&lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt; 要被拷貝的源檔案名稱

​<code>​dest​</code>​&lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt; 拷貝操作的目标檔案名

​<code>​flags​</code>​&lt;number&gt; 拷貝操作修飾符 預設:​<code>​0​</code>​

異步的将 ​<code>​src​</code>​ 拷貝到 ​<code>​dest​</code>​。Asynchronously copies ​<code>​src​</code>​ to ​<code>​dest​</code>​. 預設情況下,如果 ​<code>​dest​</code>​ 已經存在會被覆寫。回調函數沒有給出除了異常以外的參數。Node.js 不能保證拷貝操作的原子性。如果目标檔案打開後出現錯誤,Node.js 将嘗試删除它。

​<code>​flags​</code>​ 是一個可選的整數,用于指定行為的拷貝操作。唯一支援的 flag 是 ​<code>​fs.constants.COPYFILE_EXCL​</code>​ ,如果 ​<code>​dest​</code>​ 已經存在,則會導緻拷貝操作失敗。

fs.constants傳回一個包含常用檔案系統操作的常量的對象。

​<code>​path​</code>​&lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt;

<code>​options​</code>​&lt;string&gt; | &lt;Object&gt;

​<code>​flags​</code>​&lt;string&gt;

​<code>​encoding​</code>​&lt;string&gt;

​<code>​fd​</code>​&lt;integer&gt;

​<code>​mode​</code>​&lt;integer&gt;

​<code>​autoClose​</code>​&lt;boolean&gt;

​<code>​start​</code>​&lt;integer&gt;

​<code>​end​</code>​&lt;integer&gt;

​<code>​highWaterMark​</code>​&lt;integer&gt;

傳回一個建立的 ​<code>​ReadStream​</code>​ 對象。

不同于在一個可讀流上設定的 ​<code>​highWaterMark​</code>​ 預設值(16 kb),該方法在相同參數下傳回的流具有 64 kb 的預設值。

​<code>​options​</code>​ 是一個帶有以下預設值的對象或字元串:

​<code>​options​</code>​ 可以包括 ​<code>​start​</code>​ 和 ​<code>​end​</code>​ 值,使其可以從檔案讀取一定範圍的位元組而不是整個檔案。 ​<code>​start​</code>​ 和 ​<code>​end​</code>​ 都是包括在内的,并且起始值是 0。 如果指定了 ​<code>​fd​</code>​ 且 ​<code>​start​</code>​ 不傳或為 ​<code>​undefined​</code>​,則 ​<code>​fs.createReadStream()​</code>​ 從目前檔案位置按順序地讀取。 ​<code>​encoding​</code>​ 可以是任何可以被 ​<code>​Buffer​</code>​ 接受的值。

如果指定了 ​<code>​fd​</code>​,則 ​<code>​ReadStream​</code>​ 會忽略 ​<code>​path​</code>​ 參數并且會使用指定的檔案描述符。 這意味着不會觸發 ​<code>​'open'​</code>​ 事件。 注意,​<code>​fd​</code>​ 應該是阻塞的;非阻塞的 ​<code>​fd​</code>​們應該傳給 ​<code>​net.Socket​</code>​。

如果 ​<code>​autoClose​</code>​ 為 ​<code>​false​</code>​,則檔案描述符不會被關閉,即使有錯誤。 應用程式需要負責關閉它,并且確定沒有檔案描述符洩漏。 如果 ​<code>​autoClose​</code>​ 被設定為 ​<code>​true​</code>​(預設),則在 ​<code>​error​</code>​ 或 ​<code>​end​</code>​ 時,檔案描述符會被自動關閉。

​<code>​mode​</code>​ 用于設定檔案模式(權限和粘結位),但僅限建立檔案時。

例子,從一個 100 位元組長的檔案中讀取最後 10 個位元組:

<code>​options​</code>​ &lt;string&gt; | &lt;Object&gt;

​<code>​flags​</code>​ &lt;string&gt;

​<code>​encoding​</code>​ &lt;string&gt;

​<code>​autoClose​</code>​ &lt;boolean&gt;

​<code>​start​</code>​ &lt;integer&gt;

傳回一個建立的 ​<code>​WriteStream​</code>​ 對象(詳見可寫流)。

‘​<code>​options​</code>​ 是一個帶有以下預設值的對象或字元串:

​<code>​options​</code>​ 也可以包括一個 ​<code>​start​</code>​ 選項,使其可以寫入資料到檔案某個位置。 如果是修改一個檔案而不是覆寫它,則需要​<code>​flags​</code>​ 模式為 ​<code>​r+​</code>​ 而不是預設的 ​<code>​w​</code>​ 模式。 

其它和fs.createReadStream(path[, options])類似。

​<code>​mode​</code>​ &lt;integer&gt; Default: ​<code>​0o777​</code>​

異步地建立目錄。 完成回調隻有一個可能的異常參數。 ​<code>​mode​</code>​ 預設為 ​<code>​0o777​</code>​。

​<code>​flags​</code>​&lt;string&gt; | &lt;number&gt;

​<code>​mode​</code>​&lt;integer&gt;Default:​<code>​0o666​</code>​

<code>​callback​</code>​&lt;Function&gt;

​<code>​flags​</code>​ 可以是:

<code>'r'</code> - 以讀取模式打開檔案。如果檔案不存在則發生異常。

<code>'r+'</code> - 以讀寫模式打開檔案。如果檔案不存在則發生異常。

<code>'rs+'</code> - 以同步讀寫模式打開檔案。指令作業系統繞過本地檔案系統緩存。

這對 NFS 挂載模式下打開檔案很有用,因為它可以讓你跳過潛在的舊本地緩存。 它對 I/O 的性能有明顯的影響,是以除非需要,否則不要使用此标志。

注意,這不會使 <code>fs.open()</code> 進入同步阻塞調用。 如果那是你想要的,則應該使用 <code>fs.openSync()</code>。

<code>'w'</code> - 以寫入模式打開檔案。檔案會被建立(如果檔案不存在)或截斷(如果檔案存在)。

<code>'wx'</code> - 類似 <code>'w'</code>,但如果 <code>path</code> 存在,則失敗。

<code>'w+'</code> - 以讀寫模式打開檔案。檔案會被建立(如果檔案不存在)或截斷(如果檔案存在)。

<code>'wx+'</code> - 類似 <code>'w+'</code>,但如果 <code>path</code> 存在,則失敗。

<code>'a'</code> - 以追加模式打開檔案。如果檔案不存在,則會被建立。

<code>'ax'</code> - 類似于 <code>'a'</code>,但如果 <code>path</code> 存在,則失敗。

<code>'a+'</code> - 以讀取和追加模式打開檔案。如果檔案不存在,則會被建立。

<code>'ax+'</code> - 類似于 <code>'a+'</code>,但如果 <code>path</code> 存在,則失敗。

​<code>​mode​</code>​ 可設定檔案模式(權限和 sticky 位),但隻有當檔案被建立時才有效。預設為 ​<code>​0o666​</code>​,可讀寫。

​<code>​buffer​</code>​&lt;Buffer&gt; | &lt;Uint8Array&gt;

​<code>​offset​</code>​&lt;integer&gt;

​<code>​length​</code>​&lt;integer&gt;

​<code>​position​</code>​&lt;integer&gt;

​<code>​bytesRead​</code>​&lt;integer&gt;

​<code>​buffer​</code>​&lt;Buffer&gt;

​<code>​buffer​</code>​ 是資料将被寫入到的 buffer。

​<code>​encoding​</code>​&lt;string&gt; 預設 = ​<code>​'utf8'​</code>​

​<code>​files​</code>​&lt;string[]&gt; | &lt;Buffer[]&gt;

回調有兩個參數 ​<code>​(err, files)​</code>​,其中 ​<code>​files​</code>​ 是目錄中不包括 ​<code>​'.'​</code>​ 和 ​<code>​'..'​</code>​ 的檔案名的數組。

​<code>​path​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt; | &lt;integer&gt; 檔案名或檔案描述符。

<code>​options​</code>​ &lt;Object&gt; | &lt;string&gt;

​<code>​encoding​</code>​ &lt;string&gt; | &lt;null&gt; 預設為 ​<code>​null​</code>​。

​<code>​flag​</code>​ &lt;string&gt; 預設為 ​<code>​'r'​</code>​。

​<code>​data​</code>​ &lt;string&gt; | &lt;Buffer&gt;

異步地讀取一個檔案的全部内容。

注意:當 ​<code>​path​</code>​ 是一個目錄時,​<code>​fs.readFile()​</code>​ 與 fs.readFileSync() 的行為與平台有關。 在 macOS、Linux 與 Windows 上,會傳回一個錯誤。 在 FreeBSD 上,會傳回目錄内容的表示。

任何指定的檔案描述符必須支援讀取。

注意:如果一個檔案描述符被指定為 ​<code>​path​</code>​,則它不會被自動關閉。

​<code>​oldPath​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt;

​<code>​newPath​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt;

異步的 ​<code>​rename(2)​</code>​。 完成回調隻有一個可能的異常參數。

異步的 ​<code>​rmdir(2)​</code>​。 完成回調隻有一個可能的異常參數。

請注意: 在檔案上(而不是目錄上)使用​<code>​fs.rmdir()​</code>​,在Windows平台将會導緻​<code>​ENOENT​</code>​錯誤,而在POSIX平台将會導緻​<code>​ENOTDIR​</code>​錯誤。

異步的 ​<code>​unlink(2)​</code>​。 完成回調隻有一個可能的異常參數。

​<code>​bytesWritten​</code>​&lt;integer&gt;

寫入 ​<code>​buffer​</code>​ 到 ​<code>​fd​</code>​ 指定的檔案。

​<code>​offset​</code>​ 決定 buffer 中被寫入的部分,​<code>​length​</code>​ 是一個整數,指定要寫入的位元組數。

​<code>​position​</code>​ 指向從檔案開始寫入資料的位置的偏移量。 如果 ​<code>​typeof position !== 'number'​</code>​,則資料從目前位置寫入。詳見 ​<code>​pwrite(2)​</code>​。

回調有三個參數 ​<code>​(err, bytesWritten, buffer)​</code>​,其中 ​<code>​bytesWritten​</code>​ 指定從 ​<code>​buffer​</code>​ 寫入了多少位元組。

如果以 ​<code>​util.promisify()​</code>​ 的形式調用該方法,則會傳回包含 ​<code>​bytesWritten​</code>​ 和 ​<code>​buffer​</code>​ 屬性的 Promise 的對象。

注意,多次對同一檔案使用 ​<code>​fs.write​</code>​ 且不等待回調,是不安全的。 對于這種情況,強烈推薦使用 ​<code>​fs.createWriteStream​</code>​。

在 Linux 上,當檔案以追加模式打開時,指定位置的寫入是不起作用的。 核心會忽略位置參數,并總是将資料追加到檔案的末尾。

​<code>​string​</code>​ &lt;string&gt;

​<code>​position​</code>​ &lt;integer&gt;

​<code>​written​</code>​ &lt;integer&gt;

寫入 ​<code>​string​</code>​ 到 ​<code>​fd​</code>​ 指定的檔案。 如果 ​<code>​string​</code>​ 不是一個字元串,則該值将被強制轉換為一個字元串。

​<code>​encoding​</code>​ 是期望的字元串編碼。

回調有三個參數 ​<code>​(err, written, string)​</code>​,其中 ​<code>​written​</code>​ 指定傳入的字元串被寫入多少位元組。 注意,寫入的位元組與字元串的字元是不同的。詳見 ​<code>​Buffer.byteLength​</code>​。

不同于寫入 ​<code>​buffer​</code>​,該方法整個字元串必須被寫入。 不能指定子字元串。 這是因為結果資料的位元組偏移量可能與字元串的偏移量不同。

​<code>​file​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;URL&gt; | &lt;integer&gt; 檔案名或檔案描述符

​<code>​data​</code>​ &lt;string&gt; | &lt;Buffer&gt; | &lt;Uint8Array&gt;

​<code>​encoding​</code>​ &lt;string&gt; | &lt;null&gt; 預設 = ​<code>​'utf8'​</code>​

​<code>​mode​</code>​ &lt;integer&gt; 預設 = ​<code>​0o666​</code>​

​<code>​flag​</code>​ &lt;string&gt; 預設 = ​<code>​'w'​</code>​

異步地寫入資料到檔案,如果檔案已經存在,則替代檔案。 ​<code>​data​</code>​ 可以是一個字元串或一個 buffer。

如果 ​<code>​data​</code>​ 是一個 buffer,則忽略 ​<code>​encoding​</code>​ 選項。它預設為 ​<code>​'utf8'​</code>​。