<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                我們先大致看看NodeJS提供了哪些和文件操作有關的API。這里并不逐一介紹每個API的使用方法,官方文檔已經做得很好了。 ## Buffer(數據塊) > **官方文檔:?**[](http://nodejs.org/api/buffer.html)[http://nodejs.org/api/buffer.html](http://nodejs.org/api/buffer.html) JS語言自身只有字符串數據類型,沒有二進制數據類型,因此NodeJS提供了一個與`String`對等的全局構造函數`Buffer`來提供對二進制數據的操作。除了可以讀取文件得到`Buffer`的實例外,還能夠直接構造,例如: ~~~ var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]); ~~~ `Buffer`與字符串類似,除了可以用`.length`屬性得到字節長度外,還可以用`[index]`方式讀取指定位置的字節,例如: ~~~ bin[0]; // => 0x68; ~~~ `Buffer`與字符串能夠互相轉化,例如可以使用指定編碼將二進制數據轉化為字符串: ~~~ var str = bin.toString('utf-8'); // => "hello" ~~~ 或者反過來,將字符串轉換為指定編碼下的二進制數據: ~~~ var bin = new Buffer('hello', 'utf-8'); // => <Buffer 68 65 6c 6c 6f> ~~~ `Buffer`與字符串有一個重要區別。字符串是只讀的,并且對字符串的任何修改得到的都是一個新字符串,原字符串保持不變。至于`Buffer`,更像是可以做指針操作的C語言數組。例如,可以用`[index]`方式直接修改某個位置的字節。 ~~~ bin[0] = 0x48; ~~~ 而`.slice`方法也不是返回一個新的`Buffer`,而更像是返回了指向原`Buffer`中間的某個位置的指針,如下所示。 ~~~ [ 0x68, 0x65, 0x6c, 0x6c, 0x6f ] ^ ^ | | bin bin.slice(2) ~~~ 因此對`.slice`方法返回的`Buffer`的修改會作用于原`Buffer`,例如: ~~~ var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]); var sub = bin.slice(2); sub[0] = 0x65; console.log(bin); // => <Buffer 68 65 65 6c 6f> ~~~ 也因此,如果想要拷貝一份`Buffer`,得首先創建一個新的`Buffer`,并通過`.copy`方法把原`Buffer`中的數據復制過去。這個類似于申請一塊新的內存,并把已有內存中的數據復制過去。以下是一個例子。 ~~~ var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]); var dup = new Buffer(bin.length); bin.copy(dup); dup[0] = 0x48; console.log(bin); // => <Buffer 68 65 6c 6c 6f> console.log(dup); // => <Buffer 48 65 65 6c 6f> ~~~ 總之,`Buffer`將JS的數據處理能力從字符串擴展到了任意二進制數據。 ## Stream(數據流) > **官方文檔:?**[](http://nodejs.org/api/stream.html)[http://nodejs.org/api/stream.html](http://nodejs.org/api/stream.html) 當內存中無法一次裝下需要處理的數據時,或者一邊讀取一邊處理更加高效時,我們就需要用到數據流。NodeJS中通過各種`Stream`來提供對數據流的操作。 以上邊的大文件拷貝程序為例,我們可以為數據來源創建一個只讀數據流,示例如下: ~~~ var rs = fs.createReadStream(pathname); rs.on('data', function (chunk) { doSomething(chunk); }); rs.on('end', function () { cleanUp(); }); ~~~ > **豆知識:**?`Stream`基于事件機制工作,所有`Stream`的實例都繼承于NodeJS提供的[EventEmitter](http://nodejs.org/api/events.html)。 上邊的代碼中`data`事件會源源不斷地被觸發,不管`doSomething`函數是否處理得過來。代碼可以繼續做如下改造,以解決這個問題。 ~~~ var rs = fs.createReadStream(src); rs.on('data', function (chunk) { rs.pause(); doSomething(chunk, function () { rs.resume(); }); }); rs.on('end', function () { cleanUp(); }); ~~~ 以上代碼給`doSomething`函數加上了回調,因此我們可以在處理數據前暫停數據讀取,并在處理數據后繼續讀取數據。 此外,我們也可以為數據目標創建一個只寫數據流,示例如下: ~~~ var rs = fs.createReadStream(src); var ws = fs.createWriteStream(dst); rs.on('data', function (chunk) { ws.write(chunk); }); rs.on('end', function () { ws.end(); }); ~~~ 我們把`doSomething`換成了往只寫數據流里寫入數據后,以上代碼看起來就像是一個文件拷貝程序了。但是以上代碼存在上邊提到的問題,如果寫入速度跟不上讀取速度的話,只寫數據流內部的緩存會爆倉。我們可以根據`.write`方法的返回值來判斷傳入的數據是寫入目標了,還是臨時放在了緩存了,并根據`drain`事件來判斷什么時候只寫數據流已經將緩存中的數據寫入目標,可以傳入下一個待寫數據了。因此代碼可以改造如下: ~~~ var rs = fs.createReadStream(src); var ws = fs.createWriteStream(dst); rs.on('data', function (chunk) { if (ws.write(chunk) === false) { rs.pause(); } }); rs.on('end', function () { ws.end(); }); ws.on('drain', function () { rs.resume(); }); ~~~ 以上代碼實現了數據從只讀數據流到只寫數據流的搬運,并包括了防爆倉控制。因為這種使用場景很多,例如上邊的大文件拷貝程序,NodeJS直接提供了`.pipe`方法來做這件事情,其內部實現方式與上邊的代碼類似。 ## File System(文件系統) > **官方文檔:?**[](http://nodejs.org/api/fs.html)[http://nodejs.org/api/fs.html](http://nodejs.org/api/fs.html) NodeJS通過`fs`內置模塊提供對文件的操作。`fs`模塊提供的API基本上可以分為以下三類: * 文件屬性讀寫。 其中常用的有`fs.stat`、`fs.chmod`、`fs.chown`等等。 * 文件內容讀寫。 其中常用的有`fs.readFile`、`fs.readdir`、`fs.writeFile`、`fs.mkdir`等等。 * 底層文件操作。 其中常用的有`fs.open`、`fs.read`、`fs.write`、`fs.close`等等。 NodeJS最精華的異步IO模型在`fs`模塊里有著充分的體現,例如上邊提到的這些API都通過回調函數傳遞結果。以`fs.readFile`為例: ~~~ fs.readFile(pathname, function (err, data) { if (err) { // Deal with error. } else { // Deal with data. } }); ~~~ 如上邊代碼所示,基本上所有`fs`模塊API的回調參數都有兩個。第一個參數在有錯誤發生時等于異常對象,第二個參數始終用于返回API方法執行結果。 此外,`fs`模塊的所有異步API都有對應的同步版本,用于無法使用異步操作時,或者同步操作更方便時的情況。同步API除了方法名的末尾多了一個`Sync`之外,異常對象與執行結果的傳遞方式也有相應變化。同樣以`fs.readFileSync`為例: ~~~ try { var data = fs.readFileSync(pathname); // Deal with data. } catch (err) { // Deal with error. } ~~~ `fs`模塊提供的API很多,這里不一一介紹,需要時請自行查閱官方文檔。 ## Path(路徑) > **官方文檔:?**[](http://nodejs.org/api/path.html)[http://nodejs.org/api/path.html](http://nodejs.org/api/path.html) 操作文件時難免不與文件路徑打交道。NodeJS提供了`path`內置模塊來簡化路徑相關操作,并提升代碼可讀性。以下分別介紹幾個常用的API。 * path.normalize 將傳入的路徑轉換為標準路徑,具體講的話,除了解析路徑中的`.`與`..`外,還能去掉多余的斜杠。如果有程序需要使用路徑作為某些數據的索引,但又允許用戶隨意輸入路徑時,就需要使用該方法保證路徑的唯一性。以下是一個例子: ~~~ var cache = {}; function store(key, value) { cache[path.normalize(key)] = value; } store('foo/bar', 1); store('foo//baz//../bar', 2); console.log(cache); // => { "foo/bar": 2 } ~~~ > **坑出沒注意:?**標準化之后的路徑里的斜杠在Windows系統下是`\`,而在Linux系統下是`/`。如果想保證任何系統下都使用`/`作為路徑分隔符的話,需要用`.replace(/\\/g, '/')`再替換一下標準路徑。 * path.join 將傳入的多個路徑拼接為標準路徑。該方法可避免手工拼接路徑字符串的繁瑣,并且能在不同系統下正確使用相應的路徑分隔符。以下是一個例子: ~~~ path.join('foo/', 'baz/', '../bar'); // => "foo/bar" ~~~ * path.extname 當我們需要根據不同文件擴展名做不同操作時,該方法就顯得很好用。以下是一個例子: ~~~ path.extname('foo/bar.js'); // => ".js" ~~~ `path`模塊提供的其余方法也不多,稍微看一下官方文檔就能全部掌握。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看