ファイル,ストリーム,外部操作
Wolframシステムファイルの読み書き | ファイルの検索 |
外部プログラム | 文字列の検索と読込み |
ストリームと低レベルの入出力 | バイナリファイル |
ファイル名と検索 | C言語とFortran形式のプログラムコードの生成 |
ファイルとディレクトリの操作 | Wolfram言語スクリプト |
原文データの読込み |
外部ファイルへのWolfram言語式の保存
式の定義やWolfram言語の結果は,コンピュータシステムのファイルに保存することができる.最も一般的なアプローチとしては,Wolfram言語の入力として適切なテキスト形式ですべての情報を保存する方法がある.このアプローチを使えば,生成されたファイルは,どのWolfram言語のバージョンで使用しても正確に読み込ませることができる.さらに,テキストファイルなので,各種の一般的なプログラム,例えば,テキストエディタでも編集ができるという利点もある.
<<file または Get["file"] | ファイルをWolfram言語の入力式として読み込み,ファイルの最後の式を返す |
FilePrint["file"] | ファイル内容の表示 |
expr>>file または Put[expr,"file"] | 式をファイルに書き出す |
expr>>>file または PutAppend[expr,"file"] | 式をファイルに追記する |
指定のファイルが見付からないときWolfram言語はメッセージを表示し,$Failedを返す:
<<file によってファイルを読むと,Wolfram言語はこれを評価した最終的な結果を返す.このときの表示を抑制するには,ファイルの最後の式の末尾をセミコロンとすればよい.あるいは明示的に最後にNullと書いてもよい.
Wolfram言語がファイルを読み込んでシンタックスエラーに出会うと,エラーを表示しファイルの残りの部分を無視し,$Failedを返す.シンタックスエラーがパッケージの途中で生じると,ここではBeginPackage等のコンテキスト操作関数が使われているが,Wolfram言語はパッケージが読まれる前のコンテキストに復帰しようと試みる.
複数のWolfram言語式の保存
Wolfram言語の入力ファイルにはいくつの式が書かれていてもよい.同一の式は何行にも渡って書かれていても構わないが,それぞれの式は新たな行に書かれていなければならない.標準的な対話的Wolfram言語セッションと同様,式は完成されると同時に評価される.しかし,対話的なセッションと異なり,ファイルに入力式を書く場合は任意の場所に空行を書いてもよく,これは無視される.
異なる形式でのWolfram言語式の保存
>>または>>>によってファイルに式を書くと,式は普通Wolfram言語の入力形で書かれる.したがってこの式を後で読み込んで評価することができる.しかし別のフォーマットで式を保存することもできる.それには書いた式をOutputForm等のフォーマット指示子に入れてやる.
Wolfram言語オブジェクトの定義の保存
ファイルを使う理由の多くは,後のWolfram言語セッションで読み込んでまた使うために,Wolfram言語オブジェクトの定義を保存しておくためである.>>や>>>等の演算子でWolfram言語の式をファイルに保存することができる.また,関数Saveを使えば,Wolfram言語オブジェクトの完全な定義を,後のWolfram言語セッションで利用するのに適した形で保存できる.
Save["file",symbol] | 記号の完全な定義をファイルに保存 |
Save["file","form"] | 名前が文字列のパターン form にマッチする記号の定義をファイルに保存 |
Save["file","context`"] | 指定したコンテキストのすべての記号の定義を保存 |
Save["file",{object1,object2,…}] | 複数のオブジェクトの定義を保存 |
新たなオブジェクトをWolfram言語で定義するとき,しばしばその定義は以前に定義した別のオブジェクトに依存することがある.今保存しようとしている定義でオブジェクトを作り出すことができるためには,その定義だけでなく,それが利用する別の定義もともに保存しておくことが重要である.関数Saveは定義の内容をチェックし,その定義に必要な別の定義も同時に保存する.しかし,不必要に多くの式を保存するのを避けるため,Saveは属性Protectedを持つ記号を保存することはない.そのような記号は組み込まれていると仮定される.関連する定義も保存されるので,Saveで書き出された出力を別のWolfram言語セッションで読み込めば,保存したときと同じオブジェクトが作られるはずである.
エンコードした形式でのWolfram言語定義の保存
Wolfram言語に読み込ませるファイルを作るとき,読んだり編集したりできるようにテキスト形式のファイルとするのが普通である.しかし,場合によっては内容をエンコードして直接読んだり修正したりできないが,Wolfram言語には読み込めるようなファイルが要求されることもある.このようなエンコードされたファイルはWolfram言語関数Encodeを使って作ることができる.
Encode["source","dest"] | source ファイルをエンコードしてファイル dest に書き出す |
<<dest | エンコードしたファイルを読み込む |
Encode["source","dest","key"] | キーを与えてエンコード |
Get["dest","key"] | キーを与えてエンコードしたファイルを読み込む |
Encode["source","dest",MachineID->"ID"] | 特定のIDを持つコンピュータでのみ読めるエンコードしたファイルを作る |
DumpSave["file.mx",symbol] | 記号の定義をWolfram言語の内部形式で保存 |
DumpSave["file.mx","context`"] | コンテキストに含まれるすべての記号の定義を保存 |
DumpSave["file.mx",{object1,object2,…}] | コンテキストに含まれる複数の記号の定義を保存 |
DumpSave["package`",objects] | 名前を指定した記号の定義の保存 |
非常に大きな定義や複雑な定義を扱うときは,テキスト形式で保存するよりWolframシステムが直接理解する内部形式で保存した方がより効率的に処理を行うことができる.内部形式で保存するにはDumpSaveを使う.
<<はWolframシステムの内部形式で書かれた定義も理解し,適切な処理を行う.注意すべきことは,この内部形式はコンピュータによって異なることである.したがって,あるコンピュータで作られた.mxファイルは別のコンピュータでも読めるとは限らない.
DumpSave["package`",…]の形式を使うとWolfram言語は定義を package.mx/system/package.mxの名前で保存する.ここで system はコンピュータの型を表す.
ほとんどすべての機種のコンピュータで,Wolfram言語から外部のプログラムやコマンドを実行することができる.しばしばWolfram言語で生成した式を外部のプログラムに受け渡し,あるいは逆に外部のプログラムの出力をWolfram言語で受け取ることが必要になる.
構造化された交信は,Wolfram言語の式をこれを扱えるように設定された外部プログラムとやり取りをすることである.その基礎になるのはWolfram Symbolic Transfer Protocol (WSTP)で,これは「WSTPと外部プログラム通信」で解説される.
<<file | ファイルを読み込む |
<<"!command" | 外部コマンドを実行し,それにより生成される出力を読み込む |
expr>>"!command" | 式expr をテキスト形式で外部コマンドにフィードする |
ReadList["!command",Number] | 外部コマンドを実行し,それにより生成されるリストを読み込む |
一般に,普通のファイル名を使えるときは,Wolfram言語ではその代りにパイプを使うことができ,その書式は感嘆符に続いて外部コマンドを書けばよい.パイプを使うときは,Wolfram言語は外部コマンドを実行し,テキストのやり取りを行う.
In[1]:= !squares 4
1 1
2 4
3 9
4 16
Wolfram言語のパイプは外部プログラムとの非構造化通信の極めて一般的なメカニズムを提供する.多くのコンピュータで,Wolfram言語のパイプはそれぞれのオペレーティングシステム固有のパイプを使って実装されている.ただし,場合によってはプロセス間の通信メカニズムが使われることもある.Wolfram言語の非構造化通信におけるひとつの制限は,パイプは一度に入力または出力の一方に使うことができるが,両方同時には使えないことである.厳密な双方向の通信はWSTPを利用するしかない.
OpenWrite[] | テンポラリファイルを固有の名前で開く |
テンポラリファイルを取り扱う際に,Wolfram言語とデータのやり取りをしない外部コマンドを実行すると便利なことが多い.これはWolfram言語関数Runを使って実現される.
Run["command",arg1,…] | Wolfram言語から外部コマンドを走らせる |
Runを実行するときに,その前に感嘆符を付けないことに注意する.Runは単に与えた引数をテキストとして受け取り,複数の引数の場合はこれらをスペースで区切ってつなぎ合せてできる文字列を外部シェルコマンドとして実行する.
Runは外部コマンドのいかなる出力も取り込むことはない.したがって,その出力が行く先はオペレーティングシステムによって決まる.同様に,Runは外部コマンドに入力を補足することはない.これは,コマンドはオペレーティングシステムによって提供されるメカニズムによって入力を受け取ることを意味する.外部コマンドがWolfram言語が利用するのと同じ入力や出力にアクセスできることもあり,便利なことも多い.しかし,Wolfram言語をフロントエンドから使っている場合は,このような使い方はかなりの混乱を招く恐れがある.
RunThrough["command",expr] | expr を入力として command を実行し,返される結果をWolfram言語に読み込む |
関数RunThroughは式のテキストをテンポラリファイルに書き出し,これを外部プログラムに入力として引き渡し,続いてその出力をWolfram言語の入力として読み込む.RunThroughでも,Runと同様,初めに感嘆符をおいてはいけない.
SystemOpen["target"] | 使用中のコンピュータシステム上で,指定されたファイル,URL,プログラムに関連付けられたその他のターゲットを開く |
SystemOpenは使用中のオペレーティングシステムでの設定を使い,URIやファイルを開く方法を決定する.ファイルを開くとき,ファイルのアイコンをダブルクリックしたときに起動するのと同じプログラムが使われる.
<<や>>は高レベルのWolframシステム入出力関数であると考えることができる.これらは,ストリームを直接扱う低レベルの入出力プリミティブを基礎として作られている.これらのプリミティブを使うことによって,Wolframシステムの入出力をもっと厳密に制御することができる.例えば,中間的なデータをファイルやパイプとやり取りをするWolframシステムプログラムを書こうとすれば,これを利用することが必要となる.
出力をストリームに書き出す低レベル手順の基本は次のようである.まず,OpenWriteまたはOpenAppendを実行してストリームを開く.これは,どのファイルまたは外部プログラムに,どんな形式で出力を書き込もうとするかをWolframシステムに指定するものである.ストリームが開かれたら,WriteやWriteStringを使って実際に式や文字列をそのストリームに書き込む.終ったら,Closeを実行してそのストリームを閉じる.
"name" | ファイルを名前で指定 |
"!name" | コマンドを名前で指定 |
InputStream["name",n] | 入力ストリーム |
OutputStream["name",n] | 出力ストリーム |
ファイルまたはパイプを開くと,Wolframシステムはそのファイルやパイプを対象とするストリームを指定するストリームオブジェクトを作る.一般に,ストリームオブジェクトはファイル名またはパイプで使われる外部コマンド名と,一意的な数を含む.
ストリームオブジェクトが持つこの数は,同一のファイルや外部コマンドに複数のストリームを作ることができるため,それらを区別するのに使われる.例えば,同じ外部プログラムにいくつかのインスタンスを開始すると,それぞれは別のストリームに接続される.
OpenWrite["file"] | ファイルに出力ストリームを開き,ファイルの内容を消去する |
OpenWrite[] | 新しい一時ファイルに出力ストリームを開く |
OpenAppend["file"] | ファイルに出力ストリームを開き,ファイルの内容に追記する準備をする |
OpenWrite["!command"] | 外部コマンドに出力ストリームを開く |
Write[stream,expr1,expr2,…] | 式の列をストリームに書き込み,最後に改行する |
WriteString[stream,str1,str2,…] | 文字列をストリームに書き込む,最後に改行しない |
Close[stream] | ストリームを閉じる |
関数Write[stream,expr]を実行すると,式が指定のストリームに書き込まれる.デフォルトではWolframシステムの入力形で書かれる.式の列を引数としてWriteを実行すると,それらの式を順にストリームに書き出す.一般に,式と式の間にスペースは挿入されない.しかし,すべての式が書かれると,Writeは常に最後に改行する.
式はすべて入力形で書かれている.1つのWriteで書かれた式は同一の行に書かれる:
WriteはWolfram言語式を完結した式として書き出す方法である.しかし,場合によってはデータを構造化されていないまま書き出したいこともある.WriteStringは任意の文字列を書き出す.WriteStringはWriteと違って,最後に改行やその他の記号を加えない.
Write[{stream1,stream2},expr1,…] | 式をストリームに書き出す |
WriteString[{stream1,stream2},str1,…] | 文字列をストリームに書き出す |
Wolframシステムでは,複数のストリームのリストを channel として定義しておくと便利である.単にこのチャンネルを指定すれば,Wolframシステムは同一のオブジェクトを複数のストリームに書き出すことができる.
標準の対話的Wolframシステムセッションでは,普通いくつかのチャンネルが利用されている.これらには特定の出力が送られる先が指定されている.したがって,例えば$Outputは標準出力の宛先が,$Messagesにはメッセージの宛先が指定されている.したがって,関数Printは基本的にWriteを$Outputに宛てて実行する.同様に,MessageはWriteを$Messagesに宛てて実行する.「メインループ」に代表的なWolframシステムセッションで使われるチャンネルのまとめがある.
WolframシステムをWolfram Symbolic Transfer Protocol (WSTP)で使っているときは普通,別な方法が取られることに注意する.すべての出力は大抵は単一のWSTPリンクに書かれる.個々の出力は型を指定したパケットという形態を取る.
ほとんどの場合,Wolframシステムの使うファイル名または外部コマンド名は,使っているコンピュータのオペレーティングシステムに準拠している.ただし,システムによっては特殊な名のストリームをサポートしている場合もある.
特別なストリーム"stdout"は出力をオペレーティングシステムの標準出力に送るためのものである.しかし,これはテキスト型インターフェースのWolframシステムでのみ使われることに注意する.もっと複雑な使い方をしているときはこのストリームは機能せず,使おうとすると混乱を招くことになる.
オプション名
|
デフォルト値
| |
FormatType | InputForm | デフォルトの出力フォーマット |
PageWidth | 78 | ページ幅の文字数 |
NumberMarks | $NumberMarks | 近似数に` を付けて表示 |
CharacterEncoding | $CharacterEncoding | 特殊文字に使う文字コード |
ストリームを開き,OutputFormを出力フォーマットのデフォルト設定とする:
式はOutputFormで書かれている:
式を書き出すときに特にフォーマットを指定すれば,これがストリームにデフォルトで設定された出力フォーマットより優先される.OutputFormやTeXForm等,Wolframシステムのフォーマット指示子を明示的に指定して,式をストリームに書き出せばよい.
オプションPageWidthはWolframシステムのドキュメントの出力のページ幅を指定する.出力はこの幅に収まるように改行される.改行したくないときはPageWidth->Infinityと指定する.しかし,普通PageWidthには出力機に合わせた数字を与える.多くのシステムでは,この値を見出すためには外部プログラムを走らせる必要がある.SetOptionsを使って,PageWidthのデフォルト値を取得する設定をすることができる.例えばPageWidth:><<"!devicewidth"とすれば,外部プログラムが起動されて適切な値が設定される.
オプションCharacterEncodingは,文字列がWriteまたはWriteStringで特定の出力ストリームに送られるとき,これに使用する文字コード規格を指定する.CharacterEncodingは,主に異なる言語に変換するとき,または出力機が解釈できない文字を受け取らないようにするために使われる.
Options[stream] | ストリームに設定されたオプションを見出す |
SetOptions[stream,opt1->val1,…] | ストリームにオプションを再設定する |
オプションFormatTypeを開いたストリームに設定し直す:
Optionsは設定されているオプションを示す:
Options[$Output] | |
SetOptions[$Output,opt1->val1,…] |
セッション中は常に,Wolframシステムは開かれているすべての入力および出力ストリームをそのオプションとともに管理しており,これはStreams[]にリストとして書かれている.これを直接見てみると便利なことがある.しかし,このリストを直接変更することはできない.これはOpenRead等の関数によって変更される.
ディレクトリ操作
Wolframシステムではすべてのファイルはディレクトリの階層に分けられて保存されている.特定のファイルを探し出すには,Wolframシステムはそのファイル名と,それが属するディレクトリとを知らなければならない.
特定の時点では,ユーザは現ディレクトリにいて,そこからの相対位置としてディレクトリを指定することができる.例えば,現ディレクトリにあるファイルには,ディレクトリの指定を省略して,単にファイル名を指定するだけでアクセスできる.
Directory[] | 現ディレクトリ |
SetDirectory["dir"] | dir を現ディレクトリに設定 |
ResetDirectory[] | 前のディレクトリに戻る |
SetDirectoryを実行するとき,ディレクトリ名はオペレーティングシステムに合わせた形式で指定することができる.例えば,Unixシステムでは,ディレクトリの階層の1つ上のレベルのディレクトリは..で指定でき,ホームディレクトリは~で指定できる.
SetDirectoryで指定するディレクトリに移行するときはいつでも,Wolfram言語はそれまでにいたディレクトリを記憶しておく.ResetDirectoryによって,このディレクトリに戻ることができる.一般に,Wolfram言語はディレクトリのスタックをDirectoryStack[]に保存している.SetDirectoryを実行するたびに新たなディレクトリがこのスタックに追加され,ResetDirectoryを実行するたびに対応するディレクトリがスタックから削除される.
ParentDirectory[] | 現ディレクトリの親ディレクトリ |
$InitialDirectory | Wolframシステムが起動時の初期ディレクトリ |
$HomeDirectory | ホームディレクトリ(定義されているとき) |
$BaseDirectory | Wolframシステムがロードするシステム規模のファイルのためのベースディレクトリ |
$UserBaseDirectory | Wolframシステムがロードするユーザ独自のファイルのためのベースディレクトリ |
$InstallationDirectory | インストールしたWolframシステムが置かれるトップレベルのディレクトリ |
ファイルの検索
Wolfram言語は指定したファイル名をスキャンし,*,$,~,?,[,",∖,'等のメタ文字が含まれているかどうかを調べる.特殊文字が見付かれば,ファイル名全体をオペレーティングシステムまたはシェルに引き渡して解釈を促す.Unixシステムでは name*や $VAR 等は,この時点で展開される.しかし一般に,Wolfram言語はオペレーティングシステムまたはシェルが返す出力を取り,これをファイルのフルネームとみなす.
ファイルから入力を得ようとする場合,Wolfram言語はさらに次の処理をする.実行しようとしている関数のオプションPathの値を参照し,それに指定された検索パスを探す.デフォルトでPathには大域変数$Pathが指定されている.
一般に,大域変数$Pathにはディレクトリを表す文字列のリストが割り当てられている.入力ファイルを指定すると,Wolfram言語はこのリストに現れるディレクトリを順に現ディレクトリに移し,その中に要求されたファイルがあるかどうかを調べる.
ファイルを探すのにFindFileを使うこともできる.
FindFile["name"] | Getおよびその関連関数によりロードされる,指定された名前のファイルを見付ける |
FileExistsQ["name"] | ファイルが存在するかどうかを判別する |
$Path上のファイルを見付ける
FindFileは$Path上のディレクトリすべてを検索し,Get,Needs,その他の関数でロードされるファイルの絶対名を返す.FileExistsQは,指定された名前のファイルが存在するかどうかを検定する.
FindFileをパッケージ名に適用すると,そのパッケージのinit.mファイルの絶対名が返される.
ディレクトリの内容の一覧
FileNames[] | 現ディレクトリにあるすべてのファイル |
FileNames["form"] | 文字列パターン form にマッチする現ディレクトリのすべてのファイルのリスト |
FileNames[{"form1","form2",…}] | 任意の文字列パターン formi にマッチする現ディレクトリのすべてのファイルのリスト |
FileNames[forms,{"dir1","dir2",…}] | 文字列パターン forms にマッチするすべての diri のディレクトリのファイルのリスト |
FileNames[forms,dirs,n] | n レベル下までのすべてのサブディレクトリに含まれるファイル |
FileNames[forms,dirs,Infinity] | すべてのサブディレクトリのファイルを含む |
FileNames[forms,$Path,Infinity] | $Pathに指定されているサブディレクトリのうちのいずれかに含まれ,名前がパターン forms にマッチするすべてのファイルを列挙 |
FileNamesはファイル名を表す文字列のリストを返す.現ディレクトリにないファイルを示すときは,現ディレクトリからの相対パスで表したファイル名となる.すべてのファイル名はそれが作られたコンピュータシステムにおけるフォーマットで与えられる.
ファイル名の作成
DirectoryName["file"] | ファイル名からディレクトリ名を抽出 |
FileNameJoin[{"directory","name"}] | ディレクトリ名とファイル名を組み合せて完全なファイル名を作る |
ParentDirectory["directory"] | ディレクトリの親ディレクトリ |
FileNameJoin[{"dir1","dir2",…,"name"}] | ディレクトリ名の階層から完全なファイル名を作る |
FileNameJoin[{"dir1","dir2",…}] | ディレクトリ名の階層からディレクトリの単一の名前を作る |
異なるコンピュータシステムでは異なる方法でファイル名が作られることに注意する.したがって,例えば,Windowsシステムでは dir:∖dir∖dir∖name の形の名前が使われ,Unixシステムでは dir/dir/name の形の名前が使われる.関数FileNameJoinは使っているコンピュータに合わせて適切なファイル名を作る.
FileNameSplit["name"] | ファイル名をディレクトリとファイル名のリストに分割する |
FileNameTake["name",…] | ファイル名の一部を抽出する |
FileNameDrop["name",…] | ファイル名の一部を削除する |
FileNameDepth["name"] | ファイル名の中のパス要素の数を得る |
$PathnameSeparator | 使用中のオペレーティングシステムで使われるパス名のセパレータ |
FileNameSplitやFileNameJoin等の関数は,ファイル名に対して追加の操作をすることができる.これらはオペレーティングシステムにより使用されるファイル名のセパレータを尊重してファイル名を適切に分割する.FileNameJoinはデフォルトで,使用中のオペレーティングシステムに適した正則形式で名前を生成するよう$PathnameSeparatorを使う.
関連ファイルの組を作るに際して,1つのファイルを読むときに別のファイルを参照できるようにしておくと便利なことがある.大域変数$InputFileNameは今入力が読み込まれているファイル名を与える.DirectoryNameとFileNameJoinを使って,関連する他のファイル名を指定することができる.
$InputFileName | 入力が現在読み込まれているファイルの名前 |
Wolfram言語でファイルを扱う場合の問題は,ファイルおよびディレクトリの名前の形式がコンピュータシステムにより異なるという点である.つまり,標準Wolfram言語パッケージを含むファイルの名前等が,システムにより大きく異なる可能性があるということである.しかし,慣用的なシーケンスを使うと,すべての氏s手生むで同じコマンドを使って標準Wolfram言語パッケージを読み込むことができる.そのためには,それぞれのパッケージで形式 name`name` のいわゆるコンテキストを定義するのである.それぞれのシステムで,すべてのファイルが定義するコンテキストに対応した名前を持つようになる.ここでコマンド<<name`name` を使うと,Wolfram言語はそのコンテキスト名を,使用中のコンピュータシステムに適したファイル名に自動的に変換する.
標準のファイル名の拡張子
file.m | Wolfram言語式を保存したテキスト形式のファイル |
file.nb | Wolframシステムノートブック形式のファイル |
file.mx | Wolfram言語式の定義を保存したDumpSave形式のファイル |
Wolframシステムのノートブック型インターフェースを使っている場合,Wolfram言語の入出力だけでなくテキスト,グラフィックス,他の文書要素を含む完全なノートブックをWolframシステムフロントエンドで保存することができる.
FileBaseName["name"] | 拡張子なしのファイルの名前 |
FileExtension["name"] | ファイル名に対するファイル拡張子 |
ただし,Wolframシステムノートブック内でフロントエンドのセルメニューを使い,特定のセルを初期化セルに指定しておけば,ノートブックを開くたびにセルの内容は自動的に評価される.
2番目のセルのセルブラケットにアルファベットのIが付いているが,これは初期化セルと呼ばれ,ノートブックが開かれるたびに評価される:
場合によっては作成した数式等をノートブックとパッケージの両方のファイル形式で保存しておくと便利である.ノートブックファイルには説明文と一緒に式を入れておけるし,パッケージファイルにはWolfram言語が直接理解できる定義だけを分けて保存しておける.このような形態のファイル保存を行うには,すべての式を初期化セルに入れておけばよい.ノートブックが保存されるたびに,もとの定義が.m形式のファイルに自動保存される.
CopyFile["file1","file2"] | file1 を file2にコピー |
RenameFile["file1","file2"] | file1 のファイル名を file2とする |
DeleteFile["file"] | ファイルの削除 |
FileByteCount["file"] | ファイルのバイト数 |
FileDate["file"] | ファイルの修正日 |
SetFileDate["file"] | ファイルの修正日を今日に設定 |
FileType["file"] |
CopyFileとRenameFileによってできるファイルの修正日はもとのファイルと同じである.FileDateは修正日をDateListが使うフォーマット{year,month,day,hour,minute,second}で返す.
CreateDirectory["name"] | 新しいディレクトリの作成 |
DeleteDirectory["name"] | 空のディレクトリの削除 |
DeleteDirectory["name",DeleteContents->True] | ディレクトリを中のファイルごと削除 |
RenameDirectory["name1","name2"] | ディレクトリ名の変更 |
CopyDirectory["name1","name2"] | ディレクトリを中のファイルごとコピー |
<<は,ファイルからWolfram言語の式を入力形で読み込む.しかし,ファイルから別のフォーマットで書かれたデータを読み込みたいこともある.例えば,外部のプログラムで生成され,スペースで区切られた数の列からなるデータがあるとする.このようなデータはWolfram言語の入力式としてそのまま読み込むわけにはいかない.関数ReadListはこのようなデータをファイルまたは入力ストリームから取り込み,Wolfram言語のリストに変換する.
ReadList["file",{Number,Number}] | ファイルから数値を読み込み,2つずつを組にしたリストとする |
ReadList["file",Table[Number,{n}]] | ファイルから数値を読み込み,n 個ずつを組にしたリストとする |
ReadList["file",Number,RecordLists->True] | |
ファイルから数値を読み込み,ファイルの各行の数を組にしたリストとする |
Fortran形式の「E」表記の数値を含むファイル:
ReadListはこの形式の数値を読むことができる:
Byte | データのバイト数を表す整数 |
Character | 単一の文字を表す文字列 |
Real | Fortran形式の数値を表す近似実数 |
Number | Fortran形式の数値を表す厳密数,または近似数 |
Word | ワードセパレータで区切られた文字列 |
Record | レコードセパレータで区切られた文字列 |
String | 改行で終る文字列 |
Expression | 完全なWolfram言語の式 |
Hold[Expression] | 完全なWolfram言語の式をHoldの中に入れて返す |
ReadListでファイルに書かれたワードを読み込むことができる.このとき,ワードセパレータで区切られた任意の文字列がワードとみなされる.ワードセパレータはオプションWordSeparatorsによって指定することができる.デフォルトではスペースとタブがワードセパレータとなっているが,それ以外の句読点はワードの部分とみなされる.いずれの場合も,複数のワードセパレータが続いて現れても,1つとみなされる.これらのワードセパレータはReadListが返すワードの部分となることはない.
オプション
|
デフォルト値
| |
RecordLists | False | それぞれのレコードを別々のリストとする |
RecordSeparators | {"\r\n", "\n","\r"} | レコードセパレータ |
WordSeparators | {" ","∖t"} | ワードセパレータ |
NullRecords | False | 長さ0のレコードを保持するかどうか |
NullWords | False | 長さ0のワードを保持するかどうか |
TokenWords | {} | トークンとみなすワード |
ReadListのオプション
Wolfram言語はデータファイルをレコードの列からなるとみなす.デフォルトで,各行はそれぞれ独立したレコードとみなされる.一般に,レコードを区切るレコードセパレータをオプションRecordSeparatorsで指定することができる.レコードセパレータは必ずワードも区切ることに注意する.ワードセパレータと同様,複数のレコードセパレータが続いても,1つが有効で後は無視される.レコードセパレータがレコードの一部となることはない.
ReadList["file",Record,RecordSeparators->{}] | |
ファイル全体を1つの文字列として読み込む | |
ReadList["file",Record,RecordSeparators->{{"lsep1",…},{"rsep1",…}}] | |
lsepi と rsepi で囲まれる部分をサブリストとして読み込む |
オプションRecordSeparatorsの設定値
Wolfram言語では普通複数個のセパレータがあっても,それらは1つのセパレータとみなされる.しかし,場合によっては複数個のセパレータがあるとき,セパレータの間には「なし」のレコードまたはワードがあるとみなしたいことがある.これはNullRecords->TrueまたはNullWords->Trueとすることによって実現される.
ほとんどの場合,ワードはそれ自体ワードとみなされないセパレータによって区切られる.しかし,場合によっては,特殊なそれ自体ワードである「トークンワード」によってワードを区切ることが便利なこともある.トークンワードはリストとしてオプションTokenWordsに設定すればよい.
ReadListを使ってファイルからWolfram言語式を読むことができる.一般に,それぞれの式はたとえ複数行に渡るものでも,最後は改行で終らなければならない.
ReadListはそれが読み込むWolfram言語式に任意のオブジェクトを挿入することができる.ReadListの第2引数は,読み込むオブジェクトの型を指定するNumberやWord等の記号を含む任意の式からなる.したがって,例えば,ReadList["file",{Number,Number}]は,読み込んだ数を2つずつサブリストにする.同様に,ReadList["file",Hold[Expression]]は,読み込んだ式をHoldの中に入れる.
ファイルの最後にきても必要な数が足りないとき,その位置に記号EndOfFileが現れる:
OpenRead["file"] | ファイルからの入力ストリームを開く |
OpenRead["!command"] | パイプからの入力ストリームを開く |
Read[stream,type] | ストリームから指定の型のオブジェクトを読み込む |
Skip[stream,type] | 入力ストリームの指定の型のオブジェクトを読み飛ばす |
Skip[stream,type,n] | 入力ストリームの指定の型のn 個のオブジェクトを読み飛ばす |
Close[stream] | 入力ストリームを閉じる |
ReadListは所定のファイルまたは入力ストリームのすべてのデータを一度に読み込む.しかし,ときには,例えば次のデータが何かを予測しながら,1つずつ順にデータを取り込みたいことがある.
ファイルから個々のデータを読むとき,Wolfram言語はファイルにおけるカレントポイント(現在地)を覚えている.OpenReadを実行すると,Wolfram言語はファイルからの入力ストリームを開き,カレントポイントをファイルの先頭に置くReadでファイルからオブジェクトを読み込むたびに,Wolfram言語はカレントポイントを読み込んだオブジェクトの直後へ移動する.Skipを使えば,オブジェクトを読み込まずに複数のオブジェクトを飛び越してカレントポイントを移動することができる.
FindList["file","text"] | ファイルにおいて指定のテキストを含むすべての行のリスト |
FindList["file","text",n] | ファイルにおいて指定のテキストを含む n 個の行のリスト |
FindList["file",{"text1","text2",…}] | ファイルにおいてテキスト texti のいずれかを含む行のリスト |
デフォルトで,FindListはファイルの各行を順にスキャンし,指定したテキストを含む行を返す.しかし,一般に,FindListがレコードを順にスキャンし,指定のテキストを含むそれぞれのレコードを返すようにすることもできる.ReadListと同様に,オプションRecordSeparatorsによってレコードセパレータを指定することができる.RecordSeparatorsにペアのリストを与えることによって,左と右のセパレータを別々に指定することもできる.この場合,FindListは左右のセパレータに囲まれたテキストのみを検索するようにできる.
ピリオドで区切られた「文」で,Andを含むものを探し出す:
オプション名
|
デフォルト値
| |
RecordSeparators | {"∖n"} | レコードセパレータ |
AnchoredSearch | False | 検索するテキストはレコードの先頭である |
WordSeparators | {" ","∖t"} | ワードセパレータ |
WordSearch | False | 検索するテキストは独立したワードである |
IgnoreCase | False | 大文字と小文字を区別しない |
FindListのオプション
ファイルの各行の行頭に現れるHereのみを検索する:
一般に,FindListはレコードの任意の位置に現れるテキストを探し出す.しかし,オプションWordSearch->Trueを設定すると,FindListは指定のテキストがレコードの中の独立したワードとして現れるものだけを検索する.オプションWordSeparatorsはワードのセパレータを指定する.
FindList[{"file1","file2",…},"text"] | テキストを filei のいずれかにあれば探し出す |
FindList["!command",…] | 外部コマンドを実行し,その出力に含まれるテキストを探し出す |
OpenRead["file"] | ファイルからの入力ストリームを開く |
OpenRead["!command"] | 入力するためにパイプを開く |
Find[stream,text] | 次に現れる text を見出す |
Close[stream] | ストリームを閉じる |
Findを使うには,まずOpenReadによって明示的に入力ストリームを開かなければならない.その後は,Findをこのストリームに対して実行するたびに指定のテキストが探され,カレントポイントをテキストが見出されたレコードの直後に移す.その結果,Findを数回繰り返して順にテキストを検索することができる.
Andを含む初めの行を見出す:
Readはその行の先頭の語を読み込む:
StreamPosition[stream] | 開いているストリームにおけるカレントポイントの位置を見出す |
SetStreamPosition[stream,n] | カレントポイントを設定する |
SetStreamPosition[stream,0] | カレントポイントをストリームの先頭に設定する |
SetStreamPosition[stream,Infinity] | カレントポイントをストリームの最後に設定する |
ストリームにおけるカレントポイントがどこにあるかを知りたいこと,またこれを再設定したいことがある.ほとんどのコンピュータシステムでは,StreamPositionはカレントポイントの位置を,ストリームの先頭からの位置に対応するバイト数を表す整数で返す.
Readは初めの行の残りの部分を読み込む:
ReadやFind等の関数は,外部ファイルから読み込むテキストやデータを処理するのに使われることが多い.しかし,場合によっては,これらの関数をWolfram言語の中で文字列を処理するのに使うと便利なこともある.これには関数StringToStreamがあり,入力ストリームを開くが,外部ファイルからでなく,Wolfram言語の文字列から文字を取り出す.
StringToStream["string"] | 文字列から読み出すために入力ストリームを開く |
Close[stream] | 入力ストリームを閉じる |
文字列からの入力ストリームはファイルへのストリームと同様に機能する.任意の時点で,ストリームにおいてカレントポイントが設定され,それはRead等の関数が実行されると移動する.カレントポイントの位置は,関数StreamPosition[stream]によって文字列の先頭からの文字数を表す整数で示される.SetStreamPosition[stream,n]を使って明示的にカレントポイントの位置を設定することができる.
ストリームから何かを読み込もうとすると,EndOfFileを得る:
特に大量のテキストデータを処理するときは,Wolfram言語に長い文字列を読み込ませることが普通で,この場合StringToStreamを使うとWolfram言語の中でこの文字列を処理することができる.StringToStreamを使って一度入力ストリームを開けば,文字列を読んだり検索したりするのに,ファイルの項で述べたどの関数でも使うことができる.
ReadやWriteのような関数は普通の印刷可能なテキストを取り扱う.しかし,外部のデータファイルやデバイスを扱うには,さらに下がったレベルで実際のバイナリデータに対して直接作業する必要があることもある.これにはBinaryReadとBinaryWriteを使うことができる.
BinaryRead[stream] | 1バイトを読む |
BinaryRead[stream,type] | 指定の型のオブジェクトを読む |
BinaryRead[stream,{type1,type2,…}] | オブジェクトのリストを読む |
BinaryWrite[stream,b] | 1バイトを書き出す |
BinaryWrite[stream,{b1,b2,…}] | 一連のバイトを書き出す |
BinaryWrite[stream,"string"] | 文字列中の文字を書き出す |
BinaryWrite[stream,x,type] | 指定された型のオブジェクトを書き出す |
BinaryWrite[stream,{x1,x2,…},type] | 一連のオブジェクトを書き出す |
BinaryWrite[stream,{x1,x2,…},{type1,type2,…}] | |
異なる型のオブジェクトを書き出す |
"Byte" | 8ビットの符号なしの整数 |
"Character8" | 8ビットの文字 |
"Character16" | 16ビットの文字 |
"Complex64" | IEEE単精度複素数 |
"Complex128" | IEEE倍精度複素数 |
"Complex256" | IEEE4倍精度複素数 |
"Integer8" | 8ビット符号付き整数 |
"Integer16" | 16ビット符号付き整数 |
"Integer32" | 32ビット符号付き整数 |
"Integer64" | 64ビット符号付き整数 |
"Integer128" | 128ビット符号付き整数 |
"Real32" | IEEE単精度実数 |
"Real64" | IEEE倍精度実数 |
"Real128" | IEEE4倍精度実数 |
"TerminatedString" | 8ビット文字のヌルで終る文字列 |
"UnsignedInteger8" | 8ビットの符号なしの整数 |
"UnsignedInteger16" | 16ビットの符号なしの整数 |
"UnsignedInteger32" | 32ビットの符号なしの整数 |
"UnsignedInteger64" | 64ビットの符号なしの整数 |
"UnsignedInteger128" | 128ビットの符号なしの整数 |
BinaryWriteは自動的にファイルストリームを開く.これで閉じる:
ReadやWriteのようにBinaryReadとBinaryWriteはストリームを取り扱う.しかし,ファイル名を指定した場合は,指定されたファイルを自動的にストリームのように開く.直接ストリームを作成する場合はOpenReadまたはOpenWriteを使うことができる.コンピュータシステムによっては,BinaryRead,BinaryWriteでストリームを使うには,オプションの設定,BinaryFormat->Trueが改行の解釈の問題等からデータが壊れることを防ぐために必要である.
Wolfram言語の使用には,通常コンピュータ内部でデータがどのように格納されているか考える必要はない.BinaryReadとBinaryWriteはこの例外であり,微妙な問題として注意しておきたいのは,コンピュータによって数を表すバイトが$ByteOrderingの設定として指定されているのと違う階級のものを使うことがあることである.
BinaryReadList["file"] | ファイルにあるすべてのバイトを読み込む |
BinaryReadList["file",type] | すべてのデータをある型のオブジェクトとして読み込む |
BinaryReadList["file",{type1,type2,…}] | データを一連の型のオブジェクトとして扱う |
BinaryReadList["file",types,n] | 最初の n 個のオブジェクトだけを読み込む |
BinaryReadとBinaryWriteでは,生のバイナリデータの読込みと書出しは完全にフレキシブルに行うことができる.しかし実際の作業ではひとつのすでに決められた型を使って作業することがより望まれる.ImportとExportではこれが可能である.
多くの複雑な型に加えてImportとExportはBinaryReadとBinaryWriteが扱うのと同じ型の一連の同一データ要素を含んだファイルをサポートしている.また,これらの関数は0,1で表される個々のバイナリビットを含んだ"Bit"形式をサポートしている.
読者の中にはC言語やFortranを使ったプログラムを開発していて,Wolfram言語で作った数式をプログラムのソースコードに取り込みたいという人もいるだろう.Wolfram言語には特別な記述変換機能が備えられているので,それを使うことで,数式をこれらの言語記述に変換することができるようになっている.
CForm[expr] | C言語形式で式 expr を出力する |
FortranForm[expr] | Fortran形式で式 expr を出力する |
Export[file,expr,"C"] | expr を計算するC関数を書く |
C言語形式にするならこうする.Power等のオブジェクトに対応したマクロは,ほとんどのWolfram言語のバージョンに標準添付されるCヘッダファイルmdefs.hに定義されている:
C関数全体がWolfram言語のCompiledFunction式から計算される:
Wolfram言語式をCやFortranに変換したいというよくある動機の一つに,数値的に速く評価させるためというものがある.しかし,CおよびFortranがWolfram言語より効率的となり得る唯一の理由は,これらの言語ではユーザが使用するそれぞれの変数の型(整数,実数,配列等)をその場で常に指定するためということである.
Wolfram言語関数Compileはそのような前提をWolfram言語内で行い,非常に効率的な内部コードを生成する.これはCompilationTargetを"C"に設定することでより高速に実行させることができる.
Compile[x,expr] | 式を効率的な内部コードにコンパイルする |
Compile[x,expr,CompilationTarget->"C"] | Cコードにコンパイルし,Wolfram言語にリンクし直す |
スクリプトファイル
Wolfram言語スクリプトはWolfram言語セッションで逐次評価するWolfram言語コマンドを含むファイルである.コマンドを何度も繰り返す必要がある場合は,スクリプトを書くと便利である.これらのコマンドを集めることで,どのコマンドを省略することもなく,特定の順序で確実に評価するようにできる.複雑で長い計算を実行する場合,これは非常に重要である.
Wolfram言語をインタラクティブに使う場合,スクリプトファイルに含まれるコマンドはGetを使って評価することができる.この関数は自分で書いたコードや他の.wlファイルの中で,プログラムで使うこともできる.
スクリプトファイルの構造には必要条件はない.ファイルで与えられるWolfram言語コマンドの列が読まれ,逐次評価される.コードがただのコマンドのリストよりも複雑なものである場合は,「パッケージ」で説明するように,より構造化されたパッケージを書いた方がよいかもしれない.
Wolfram言語スクリプトは,インタラクティブなセッションが必要ないとき,つまり,スクリプトが実行される必要のある1つの計算をカプセル化するときにより便利である.例えば,計算に線形代数,最適化,数値積分,微分方程式の解法等の要求の高い計算タスクが含まれている場合や,タイプセット,動的インタラクティブ機能,ノートブックを使わない場合等である.
スクリプトは通常の.wlパッケージファイル,あるいは.wlsスクリプトファイルで保存することができる.どちらのファイルの内容も同じであり,一連のWolfram言語式の他,Unixのようなオペレーティングシステム(Unix Script Executablesを参照)ではオプショナルの先頭のシバン行が含まれる.ファイルタイプ間の唯一の違いは,ダブルクリックしたときの動作である.パッケージファイルをダブルクリックすると,ノートブックのパッケージエディタでファイルが開くが,スクリプトファイルをダブルクリックすると,オペレーティングシステムでサポートされている場合,そのファイルは実行される. これは特に,プログラムとファイル拡張子とは関連付けができても特定のファイルとは関連付けができないWindowsで便利である.スクリプトファイルはノートブックインターフェースで編集することができるが,ファイル ▶ 開くを使って開かなければならない.
ローカルカーネルでスクリプトを実行する
$ "%ProgramFiles%\Wolfram Research\Mathematica\14.1\wolfram" -script file.wl
$ /Applications/Mathematica.app/Contents/MacOS/wolfram -script file.wl
$ wolfram -script file.wl
-scriptコマンドラインオプションはWolfram言語カーネルが特殊スクリプトモード(すなわちバッチモード)で実行されるよう指定する.このモードでは,カーネルは指定されたファイルを読み込み,そのコマンドを逐次評価する.カーネルは,出力関数のPageWidthオプションをInfinityに設定することでデフォルトの改行をオフにし,In[]およびOut[]ラベルを出力しないようにすることができる.このモードで実行すると,標準の入出力チャンネル,,はリダイレクトされず,出力はInputFormでフォーマットされる.
-scriptオプションでwolframを実行することはGetコマンドを使ってファイルを読み込むことと同じである.ただ1点違うのは,前者はファイルの中の最後のコマンドが評価された後,カーネルが終了するという点である.この動作はWolfram Symbolic Transfer Protocol (WSTP)接続や,スクリプトを実行している外部プロセスに影響を及ぼす可能性がある.
WolframScriptを使ってスクリプトを実行する
$ wolframscript -file file.wl
WolframScriptは最適なローカルカーネルを探してスクリプトを実行する.ローカルカーネルが見付からなかったら,クラウドに接続してそこでスクリプトを実行する.プログラムは,評価のためにどのローカルカーネルまたはクラウドカーネルを使うかを制御するために,さまざまなフラグを受け入れる.またプログラムは,スクリプトパラメータも設定する.これによって,スクリプトがどのように起動されたか,あるいはどのような入力を受け取ったかに基づいて,スクリプトの動作を変更することができる.WolframScriptを使うもう一つの利点は,入出力が完全にバッファされるため,さまざまな変換が入出力に適用されるという点である.これらのオプションについてはすべてWolframScriptページに例題付きで記載されている.
WindowsとLinuxでは,WolframScriptは通常Wolframシステムとともにインストールされる.Macでは,Wolframシステムにバンドルされている"Extras"インストーラを実行してWolframScriptを取得する必要がある.これらのインストーラはデフォルトでwolframscriptをPATH上に置く.
Unixスクリプト実行ファイル
Unixのようなオペレーティングシステム,およびcygwinやMinGW等のWindowsでのUnix環境では,実行可能にすることができて通常の実行可能プログラムとして実行することのできるスクリプトを書くことができる.これはファイルの最初に「インタプリタ」行を置くことで行うことができる.Wolfram言語コマンドを含むスクリプトでも同じことができる.
「インタプリタ」行は行頭の2つの記号「#!」から始まり,次に実行可能ファイルへの絶対パス,その次に他の引数と続く.プラットフォームやマシン間での互換性を最大にするために,WolframScriptは以下のようにヘルパー/usr/bin/envで起動することをお勧めする.envプログラムがPATH上でwolframscriptを探し,正しく起動する.
#!/usr/bin/env wolframscript
(* generate high-precision samples of a mixed distribution *)
Print /@ RandomVariate[MixtureDistribution[
{1,2},
{NormalDistribution[1,2/10],
NormalDistribution[3,1/10]}],
10, WorkingPrecision -> 50]
$ chmod a+x script.wls
$ ./script.wls
インタプリタ行は,そのインタプリタに対する他のパラメータを追加で含むことができる.利用可能なパラメータはWolframScriptページで指定されている.
#!/usr/bin/env wolframscript -linewise -format XML
Wolfram言語スクリプトは.wlまたは.wls拡張子を持っている必要はない.実行可能スクリプトはUnixオペレーティングシステムの他のプログラムと同様のフル機能のプログラムなので,ジョブコントロール等に従って,他のスクリプト内,パイプ内で使うことができる.それぞれのWolfram言語スクリプトはそれ自身のWolframKernelを起動し,変数や定義を共有しない.Wolfram言語スクリプトを同時に実行することは,同時に起動できるカーネル数に関するライセンスの制約を受けることがある.
実行可能スクリプトファイルはインタラクティブなWolfram言語セッションに透過的に読み込んで評価することができる.Getコマンドは,スクリプトが#!の記号で始まっている場合,通常スクリプトの1行目を無視する.
envプログラムを使わないようにすることもできるが,その場合はwolframscriptへのパスが絶対パスでなければならない.スクリプトの起動に使われたオペレーティングシステムのメカニズムは,ファイルを探すのにPATHも使わなければ他の手段も使わない.さらに,インタープリタへのパスにはスペースがあってはならない.
Windowsでのスクリプト
スタンドアロンのスクリプトはWindowsでも使うことができる.Unixのようなオペレーティングシステムとは異なり,これらのスクリプトには拡張子.wlsがないとWolfram言語スクリプトとして認識されない.このようなスクリプトは,Windowsエクスプローラからダブルクリックで起動することも,コマンドプロンプトで名前をタイプして起動することもできる.Unixのインタープリタ行がある場合,それはこのメカニズムによって無視される.
> file.wls
コマンドプロンプトでは,ファイル名の後に追加の引数を渡すことができる.これらの引数はWolframScriptによって見られるわけではなく,次のセクションで説明するように,パラメータとしてスクリプトに渡される.
> file.wls arg1 arg2
スクリプトパラメータ
Wolfram言語スクリプトを実行するとき,コマンドラインでパラメータを指定することによりスクリプトの動作を変更したいと思うこともあるだろう.Wolfram言語コードでは$ScriptCommandLineによりWolfram言語スクリプトに渡されたパラメータにアクセスすることができる.さらに,標準的な入力の内容は,変数$ScriptInputStringの文字列として処理されるために利用できる.
$ScriptCommandLine | スクリプトを起動するコマンドライン |
$ScriptInputString | スクリプトに与えられる標準的な入力の内容 |
#!/usr/bin/env wolframscript
(* generate "num" samples of a mixed distribution *)
num = ToExpression[$ScriptCommandLine[[2]]];
Print /@ RandomVariate[
MixtureDistribution[
{1, 2},
{NormalDistribution[1, 0.2],
NormalDistribution[3, 0.1]}
], num, WorkingPrecision -> 50]
$ ./file.wls 10
> file.wls 10
スクリプト内でアクセスされる場合,$ScriptCommandLineは第1要素としてスクリプトの名前を含み,残りはコマンドラインの引数である.$ScriptCommandLineは標準のargv[]規約に従う.これはインタープリタ,あるいは#!行でインタープリタに渡される引数へのパスを完全に隠していることに注目のこと.
Unixのようなオペレーティングシステムのスクリプトの実行方法があるため,$ScriptCommandLineはWolfram言語カーネルがwolframscriptを介して起動されたときだけ非空のリストに設定される.スクリプトがバッチモードおよびスタンドアロンのUnixスクリプトの両方で実行されるように意図されている場合,現在の実行モードは$ScriptCommandLine==={}を評価して決定することができる.その後,$ScriptCommandLineか$CommandLineのどちらかを使ってコマンドライン引数にアクセスする.