三日間node入門(day 1)
13444 ワード
1.はじめに
目次:インストール(言わないで、ネット上で探します) モジュール コードの組織と導入 ファイルアクション 本明細書のコマンド動作
疑問や文章に誤りがある場合は、コメントエリアで指摘してください.私信では他の人には見られないので、がんばって一緒に進みます~~(゜▽゜*)♪
2.モジュール
各ファイルはモジュールであり、ファイルのパスはモジュール名です.各モジュールでは、
1つのモジュールのコードは、初期化時に1回のみ実行され、その後、繰り返し呼び出しのためにキャッシュされます.
a.require
あるモジュールで、別のモジュールをロードし、エクスポートオブジェクトを返す方法です.絶対パスではなく相対パスを入力することを推奨します.
b.exports
1つのオブジェクトは、現在のモジュールのエクスポートオブジェクトであり、メソッドまたはプロパティをエクスポートするために使用され、他のモジュールは
c.module
現在のモジュールに関する情報にアクセスできるオブジェクトで、「≪関連プロパティの表示|View Related Properties|emdw≫」をクリックします.最も多くの用途は、現在のモジュールのエクスポートモジュールを置き換えることです.デフォルトのエクスポート値が空のオブジェクトである場合、関数に変更します.
d.メインモジュール
Nodeはメインモジュールと呼ばれるエントリファイルが1つしかありません.コマンドラインを呼び出して有効にする必要があります.
1つのファイルで同じモジュールを複数回呼び出すと、導入されたモジュールの内部変数は1回だけ初期化され、新しいメモリは開かれません.
3.コードの組織と配置
a.モジュールの経路解析規則
前章から
内蔵モジュール
組み込みモジュールはパス解析がなく、モジュールのエクスポートオブジェクトに直接戻ります.
node_modules
ほとんどのサードパーティ製モジュールはこのディレクトリにインストールされており、node_は導入時に直接無視されます.modulesフォルダの前のパスは、直接導入すればいいです.
たとえば、このパスは次のようになります.
導入時
NODE_PATH環境変数
定義NODE_PATH環境変数、例えば
b.バッグ
複数のサブモジュールからなるモジュールをパッケージと呼び、すべてのサブモジュールを同じディレクトリの下に配置し、npmパッケージを書いた人は、この大きなモジュールにエントリファイルが必要であることを知っています.エントリファイル名がindexであれば、導入時に直接前のパスを書けばいいです.
c.コマンドライン
栗を挙げると、コマンドラインプログラムがあり、関連パラメータが入力され、印刷されることを望んでいます.
この使用方法はコマンドラインプログラムに似ていません.次が望ましい方法です.
Linux
Linuxでは、jsファイルをshellスクリプトとして実行できます.上記の効果を達成するには、次の手順に従います. shellスクリプトでは、 node-echo.jsファイル実行権限 を付与 PATH環境変数の下でディレクトリを指定します.たとえば、
このように処理すると、任意のディレクトリで
Windows
WindowsではLinuxとは全く異なり、.cmdファイルで問題を解決する必要があります.node-echo.jsが
このように処理すると、任意のディレクトリで
プロジェクトカタログ標準サンプル
d.NPM
サードパーティ製パッケージのダウンロード
自分のパッケージを公開
まずnpmにアカウントを登録し、npm initのヒントに従って関連情報を記入し、最後に
3.ファイル操作
a.fsモジュール
Nodeは基本的なファイル操作apiしか提供していませんが、ファイルコピーという高度な操作はありません.ここではまず手を練習します.
ファイルコピー
ディレクトリの下に入り、ディレクトリの下のtest.pyファイルをフォルダの下のtest 2.pyにコピーする場合は、コマンドを入力します.
以上のプログラムは、
大きなファイルコピー
上のファイルが小さいファイルをコピーするのは大した問題はありませんが、大きいファイルを読むとメモリがパンクします.大きいファイルを読むには少しだけ読んで書くしかありません.完成するまで、上のプログラムについては以下のように改造する必要があります.
b.Buffer
jsにはバイナリデータ型はなく、nodeはStringと対等な全劇構造関数
BufferとStringタイプの差は多くなく、length属性でバイト長を読み取ることもできるし、
もちろん、彼らにも違いがあります.文字列は読み取り専用で、この文字列は変更されないという意味ではなく、バイトの位置を個別に変更するという意味で、この位置は変更されませんが、Bufferは異なり、Bufferを変更することは配列を変更するようになり、ある位置の値を直接変更することができます.
したがって、bufferをコピーするには、
c.Stream
メモリに処理するデータが一度に入らない場合や、読みながら処理する必要がある場合は、データストリームを使用する必要があります.ノードでは、様々な
Streamはイベントメカニズムに基づいて動作し、すべてのStreamのインスタンスはNodeJSが提供するEventEmitterに継承されます.上記のdataイベントは絶えずトリガーされますが、dataイベントの関数は毎回実行されるわけではありません.この問題は以下の方法で解決できます.
書き込み専用データストリームの作成
ただし、上記のプログラムでは、書き込み速度が読み取り速度に追いつかないと内部キャッシュがパンクするという問題があります.
d.その他のファイル操作
(a)ファイル属性の読み書き
ファイルのプロパティの取得
fs.stat
読み書き権限の変更
fs.chmod
権限707、777の設定について
ファイル所有権の変更
fs.chown
(b)ファイル内容の読み書き
ファイルの内容を読み込む
fs.readFile
ファイルディレクトリの読み込み
fs.readdir
ファイルの書き込み
ファイルが存在する場合は上書きされます
fs.writeFile
ディレクトリの作成
ディレクトリが存在する場合、例外が放出されます.
fs.mkdir
(c)下位ファイル操作
ファイルを開く/閉じる
fs.open fs.close
ファイルデータの読み込み
fs.readは、指定されたファイル記述子fdに基づいてファイルデータを読み出し、bufferが指すバッファオブジェクトに書き込む.readFileに対してより下位のインタフェースが提供する.
一般的には、バッファとファイルポインタを手動で管理する必要があるため、ファイルのサイズが分からない場合は特に面倒なことになります.
ファイル記述子に従ってファイルを書き込む
fs.writeこの方法はより下位レベルの操作を提供し、実際の応用ではマルチfs.writeFile()の使用を推奨する.
以上説明した方法はすべて非同期で呼び出され、それぞれ対応する同期方法もあり、
e.Path
Nodeには、パス関連の操作を簡素化し、コードの可読性を向上させるためのいくつかの組み込みモジュールが用意されています.
パスの標準化
path.normalize(path)は、入力されたパスを標準のパスに変換し、余分なスラッシュを取り除くことができます.しかし、異なるオペレーティングシステムでは、解析後のスラッシュが異なります.
接続パス区切り
pathクリップを接続し、パスを正規化します.path.join
pathの拡張子の取得
ファイルの拡張子を返し、最後の
目次:
$ node node_test.js test.py test.py1
process.argv[2]
はtest.py
です.疑問や文章に誤りがある場合は、コメントエリアで指摘してください.私信では他の人には見られないので、がんばって一緒に進みます~~(゜▽゜*)♪
2.モジュール
各ファイルはモジュールであり、ファイルのパスはモジュール名です.各モジュールでは、
require
、exports
、module
の3つの変数が使用できます.1つのモジュールのコードは、初期化時に1回のみ実行され、その後、繰り返し呼び出しのためにキャッシュされます.
a.require
あるモジュールで、別のモジュールをロードし、エクスポートオブジェクトを返す方法です.絶対パスではなく相対パスを入力することを推奨します.
const foo1 = require('./foo') // .js
const data = require('./data.json') // json
b.exports
1つのオブジェクトは、現在のモジュールのエクスポートオブジェクトであり、メソッドまたはプロパティをエクスポートするために使用され、他のモジュールは
require
メソッドを使用して現在のモジュールのエクスポートオブジェクトを呼び出すことができます.exports.sayName=function(name){
console.log('Hi' +name)
}
c.module
現在のモジュールに関する情報にアクセスできるオブジェクトで、「≪関連プロパティの表示|View Related Properties|emdw≫」をクリックします.最も多くの用途は、現在のモジュールのエクスポートモジュールを置き換えることです.デフォルトのエクスポート値が空のオブジェクトである場合、関数に変更します.
module.exports = function () {
console.log('test');
};
d.メインモジュール
Nodeはメインモジュールと呼ばれるエントリファイルが1つしかありません.コマンドラインを呼び出して有効にする必要があります.
node main.js
1つのファイルで同じモジュールを複数回呼び出すと、導入されたモジュールの内部変数は1回だけ初期化され、新しいメモリは開かれません.
3.コードの組織と配置
a.モジュールの経路解析規則
前章から
require
が相対経路と絶対経路をサポートすることを知った.しかし、この導入方式は、後期メンテナンスでファイルの保存場所を変更した場合、参照したファイルでも関連パスを変更し、一発で全身を動かす.require
には、3つ目のパスの書き方もあります.内蔵モジュール
組み込みモジュールはパス解析がなく、モジュールのエクスポートオブジェクトに直接戻ります.
const fs=require('fs')
node_modules
ほとんどのサードパーティ製モジュールはこのディレクトリにインストールされており、node_は導入時に直接無視されます.modulesフォルダの前のパスは、直接導入すればいいです.
たとえば、このパスは次のようになります.
/mytac/node_modules/app
導入時
const app=require('app')
NODE_PATH環境変数
定義NODE_PATH環境変数、例えば
NODE_PATH=/a/b/c
require('file')
を参照すると、nodeは次のパスを試みます./a/b/c/file
b.バッグ
複数のサブモジュールからなるモジュールをパッケージと呼び、すべてのサブモジュールを同じディレクトリの下に配置し、npmパッケージを書いた人は、この大きなモジュールにエントリファイルが必要であることを知っています.エントリファイル名がindexであれば、導入時に直接前のパスを書けばいいです.
const app=require('application')
//
const app=require('application/index')
c.コマンドライン
栗を挙げると、コマンドラインプログラムがあり、関連パラメータが入力され、印刷されることを望んでいます.
$ node myapp/src/util/node-echo.js Hello world
Hello world
この使用方法はコマンドラインプログラムに似ていません.次が望ましい方法です.
$ node-echo Hello world
Linux
Linuxでは、jsファイルをshellスクリプトとして実行できます.上記の効果を達成するには、次の手順に従います.
#!
注釈で現在のスクリプトの解釈器を指定し、まずnode-echo.jsファイルの上部にこの注釈を追加し、スクリプトがnodeで解析する必要があることを証明します.#! /myapp/src/util/env node
$ chmod +x /myapp/src/util/node-echo.js
/myapp/src/util/
の下でソフトチェーンファイルを作成します.ファイル名は、使用する端末コマンドと同じ名前です.コマンドは次のとおりです.$ sudo ln -s /myapp/src/util/node-echo.js /myapp/src/util/node-echo
このように処理すると、任意のディレクトリで
node-echo
コマンドを使用できますよ~Windows
WindowsではLinuxとは全く異なり、.cmdファイルで問題を解決する必要があります.node-echo.jsが
C:\myapp\src\util
ディレクトリに格納され、PATH環境変数に追加されている場合は、次のようにディレクトリの下にnode-echo.cmd
というファイルを新規作成する必要があります.@node "C:\myapp\src\util
ode-echo.js" %*
このように処理すると、任意のディレクトリで
node-echo
コマンドを使用できますよ~プロジェクトカタログ標準サンプル
- /home/user/workspace/node-echo/ #
- bin/ #
node-echo
+ doc/ #
- lib/ # API
echo.js
- node_modules/ #
+ argv/
+ tests/ #
package.json #
README.md #
d.NPM
サードパーティ製パッケージのダウンロード
# package.json
$ npm install package --save
#
$ npm install package1.0.1
自分のパッケージを公開
まずnpmにアカウントを登録し、npm initのヒントに従って関連情報を記入し、最後に
npm publish
で公開すればいいです.3.ファイル操作
a.fsモジュール
Nodeは基本的なファイル操作apiしか提供していませんが、ファイルコピーという高度な操作はありません.ここではまず手を練習します.
ファイルコピー
var fs = require('fs');
function copy(src, dst) {
fs.writeFileSync(dst, fs.readFileSync(src));
}
function main(argv) {
copy(argv[0], argv[1]);
}
main(process.argv.slice(2));
ディレクトリの下に入り、ディレクトリの下のtest.pyファイルをフォルダの下のtest 2.pyにコピーする場合は、コマンドを入力します.
$ node node-echo.js test.py test2.py
以上のプログラムは、
fs.readFileSync
を介してソースパスからファイル内容を読み出し、fs.writeFileSync
を用いてターゲットパスにファイルを書き込む.processは、process.argvによってコマンドラインパラメータを取得するグローバル変数です.注目すべきはargv[0]が常にnode実行プログラムの絶対パスであり、argv[1]がメインモジュールの絶対パスであるため、入力されたパラメータはargv[2]という位置から取る必要がある.大きなファイルコピー
上のファイルが小さいファイルをコピーするのは大した問題はありませんが、大きいファイルを読むとメモリがパンクします.大きいファイルを読むには少しだけ読んで書くしかありません.完成するまで、上のプログラムについては以下のように改造する必要があります.
var fs=require('fs')
function copy(src,dist){
fs.createReadStream(src).pipe(fs.createWriteStream(dist))
}
function main(argv){
copy(argv[0],argv[1])
}
main(process.argv.slice(2))
fs.createReadStream
を使用してソースファイルの読み取り専用データストリームを作成し、fs.createWriteStream
を使用して書き込み専用データストリームを作成し、pipeメソッドで2つのデータストリームを接続します.b.Buffer
jsにはバイナリデータ型はなく、nodeはStringと対等な全劇構造関数
Buffer
を提供してバイナリデータを操作する.ファイルを読み込んでBufferのインスタンスを得ることができるほか、以下のように直接構築することもできます.var bin = new Buffer([ 0x68, 0x65, 0x6c, 0x6c, 0x6f ]);
BufferとStringタイプの差は多くなく、length属性でバイト長を読み取ることもできるし、
[index]
方式でファイル位置を読み取ることもできる.Stringと変換することもできます.たとえば、次のようにします.var str=bin.toString('utf-8') //
var bin=new Buffer('hello','utf-8') //
もちろん、彼らにも違いがあります.文字列は読み取り専用で、この文字列は変更されないという意味ではなく、バイトの位置を個別に変更するという意味で、この位置は変更されませんが、Bufferは異なり、Bufferを変更することは配列を変更するようになり、ある位置の値を直接変更することができます.
slice
メソッドを使用しても、新しいBufferを返すのではなく、ある位置のポインタを返し、そのポインタの値を変更すると元のbufferに作用します.例:var bin =new Buffer([0x68,0x65,0x6c])
var bin2=bin.slice(1)
bin2[0]=0x68
console.log(bin) // 68 68 6c
したがって、bufferをコピーするには、
copy
の方法でbufferのデータをコピーする新しいbufferを作成する必要があります.var bin =new Buffer([0x68,0x65,0x6c])
var dup=new Buffer(bin.length)
bin.copy(dup)
bin[0]=0x65
console.log(bin) //65 65 6c
console.log(dup) // 68 65 6c
c.Stream
メモリに処理するデータが一度に入らない場合や、読みながら処理する必要がある場合は、データストリームを使用する必要があります.ノードでは、様々な
Stream
によってデータストリームの動作が提供される.たとえば、データに対して読み取り専用ストリームを作成します.var fs=require('fs')
var rs=fs.createReadStream(process.argv[2])
rs.on('data',function(chunk){
// do something
console.log(chunk)
})
rs.on('end',function(){
console.log('end')
})
Streamはイベントメカニズムに基づいて動作し、すべてのStreamのインスタンスはNodeJSが提供するEventEmitterに継承されます.上記のdataイベントは絶えずトリガーされますが、dataイベントの関数は毎回実行されるわけではありません.この問題は以下の方法で解決できます.
var fs=require('fs')
var rs=fs.createReadStream(process.argv[2])
function print(data,func){
console.log(data)
func()
}
rs.on('data',function(chunk){
rs.pause()
print(chunk,function(){
rs.resume()
})
})
rs.on('end',function(){
console.log('end')
})
書き込み専用データストリームの作成
var fs=require('fs')
var rs=fs.createReadStream(process.argv[2])
var ws=fs.createWriteStream(process.argv[3])
rs.on('data',function(chunk){
ws.write(chunk)
})
rs.on('end',function(){
ws.end()
console.log('end')
})
ただし、上記のプログラムでは、書き込み速度が読み取り速度に追いつかないと内部キャッシュがパンクするという問題があります.
.write
メソッドの戻り値に基づいて、入力されたデータがターゲットファイルに書き込まれたのか、キャッシュに一時的に置かれたのかを判断し、drainイベントによってdrainは、いつデータストリームだけがキャッシュ中のデータをターゲットに書き込まれたのかを判断し、次の書き込み対象データを入力できるようになったことを意味する.var fs=require('fs')
const argvs=process.argv
var rs=fs.createReadStream(argvs[2])
var ws=fs.createWriteStream(argvs[3])
rs.on('data',function(chunk){
if(ws.write(chunk)===false){
rs.pause()
}
})
rs.on('end',function(){
ws.end()
})
ws.on('drain',function(){ //
rs.resume()
})
d.その他のファイル操作
(a)ファイル属性の読み書き
ファイルのプロパティの取得
fs.stat
var fs=require('fs')
const argvs=process.argv
fs.stat(argvs[2],function(err,stats){
if(err){
throw err
}else{
console.log(stats)
}
})
読み書き権限の変更
fs.chmod
権限707、777の設定について
var fs=require('fs')
const argvs=process.argv
function getState(path,str){
fs.stat(path,function(err,stat){
if(err){
throw err
}else{
console.log(str+stat.mode)
}
})
}
getState(argvs[2],' ')
fs.chmod(argvs[2],0777,function(err){
if(err){
throw err
console.log(' ')
}else{
getState(argvs[2],' ')
}
})
ファイル所有権の変更
fs.chown
var fs=require('fs')
const path=process.argv[2]
function getState(path){
fs.stat(path,function(err,stat){
if(err){
throw err
}else{
const {gid,uid}=stat
console.log(`gid:${gid},uid:${uid}`)
}
})
}
getState(path)
fs.chown(path,1,0,function(err){ // 1,0 uid、gid
if(err){
throw err
}else{
console.log('changed')
getState(path)
}
})
(b)ファイル内容の読み書き
ファイルの内容を読み込む
fs.readFile
var fs=require('fs')
const path=process.argv[2]
fs.readFile(path,'utf-8',function(err,data){ // , buffer
if(err){
throw err
}else{
console.log(data)
}
})
ファイルディレクトリの読み込み
fs.readdir
fs.readdir('../',function(err,files){ //
if(err){
throw err
}
console.log(files)
})
ファイルの書き込み
ファイルが存在する場合は上書きされます
fs.writeFile
fs.writeFile('test.txt','test message~~~',function(err){
if(err){
throw err
}
console.log('saved file')
})
ディレクトリの作成
ディレクトリが存在する場合、例外が放出されます.
fs.mkdir
fs.mkdir('newdir',0777,err=>{
if(err) throw err
console.log('created!')
})
(c)下位ファイル操作
ファイルを開く/閉じる
fs.open fs.close
var fs=require('fs')
const path=process.argv[2]
fs.open(path,'w',(err,fd)=>{
if(err) throw err
fs.futimes(fd,1388648322,1388648322,err=>{
if(err) throw err
console.log('futimes done')
fs.close(fd,()=>{
console.log('done')
})
})
})
ファイルデータの読み込み
fs.readは、指定されたファイル記述子fdに基づいてファイルデータを読み出し、bufferが指すバッファオブジェクトに書き込む.readFileに対してより下位のインタフェースが提供する.
一般的には、バッファとファイルポインタを手動で管理する必要があるため、ファイルのサイズが分からない場合は特に面倒なことになります.
var fs = require('fs')
const path = process.argv[2]
fs.open(path, 'r', (err, fd) => {
if (err) throw err
let buf = new Buffer(8)
fs.read(fd, buf, 1, 15, null, (err, bytesRead, buffer) => { // 0 100 null ,null
if (err) throw err
console.log('bytesRead', bytesRead)
console.log(buffer)
})
})
ファイル記述子に従ってファイルを書き込む
fs.writeこの方法はより下位レベルの操作を提供し、実際の応用ではマルチfs.writeFile()の使用を推奨する.
var fs = require('fs')
const path = process.argv[2]
fs.open(path, 'w', (err, fd) => {
if (err) throw err
const data='# hello python!'
const buf=new Buffer(data,'utf-8')
fs.write(fd,buf,0,data.length,0,(err,bytesWritten,buffer)=>{
if(err) throw err
console.log(bytesWritten)
console.log(buffer)
fs.close(fd,err=>{
if(err) throw err
console.log('file closed')
})
})
}
以上説明した方法はすべて非同期で呼び出され、それぞれ対応する同期方法もあり、
readFileSync
を例に挙げます.var fs = require('fs')
const path = process.argv[2]
try{
const data=fs.readFileSync(path)
console.log(data)
}catch(err){
console.log(err)
}
e.Path
Nodeには、パス関連の操作を簡素化し、コードの可読性を向上させるためのいくつかの組み込みモジュールが用意されています.
パスの標準化
path.normalize(path)は、入力されたパスを標準のパスに変換し、余分なスラッシュを取り除くことができます.しかし、異なるオペレーティングシステムでは、解析後のスラッシュが異なります.
var path=require('path')
const url = process.argv[0]
console.log(path.normalize(url))
接続パス区切り
pathクリップを接続し、パスを正規化します.path.join
var path=require('path')
console.log(path.join('/foo','//bar','abc','../abc')) // \foo\bar\abc
pathの拡張子の取得
ファイルの拡張子を返し、最後の
.
から切り取り、.
がなければ空の文字列を返します.path.extname const url = process.argv[2]
var path=require('path')
console.log(path.extname(url)) // .py