2015年4月1日水曜日

JavascriptでINIファイルを解読する その1

ちょっと気分を変えてプログラミングのお話を。

HTMLとJavascript、VBScriptなどでウィンドウアプリケーションが作れるという便利ツール

HTA

このHTAでINIファイルを読み込めればなぁ...と前々から思っていたのです。

そこで、さらっと書いてみたスクリプトがこれ。

function readInI (section, para) {
var i = 0;
var fs = WScript.CreateObject("Scripting.FileSystemObject");   // オブジェクト
var file = fs.OpenTextFile("text.ini", 1, false, -1);   // ファイルを開く

while (objTextStream.AtEndOfLine==false) {   // 空行が出現するまでループする
   var data[i] = file.ReadLine();   // 1行ずつ読み込む
   i++;

...下につづく

しかし、これだとエラーがでます。

「'WScript'は定義されていません」

どういうことかというと、WScriptオブジェクトはwscript.exeにしか使えないのです。要するに、HTAのJavascriptでは使えない。

ではどうするか。その答えはこれです。

// オブジェクト生成
var objFileSys = new ActiveXObject("Scripting.FileSystemObject");
var objTextStream = objFileSys.GetFile("test.ini").OpenAsTextStream(1, 0);

var data = new Array();

// ファイルが最後まで読み込まれるまでループ  読み込み
while (objTextStream.AtEndOfLine==false) {

   data[i] = objTextStream.ReadLine();
   i++;

}

...下につづく

これで正常にテキストファイルが読み込めるようになりました。

最終的なスクリプトを下に示します。


function myReadInI(mySname, myPname, myFname){

var i = 0;   // プロパティiとjはカウンタです。
var j = 0;

// オブジェクト生成
var objFileSys = new ActiveXObject("Scripting.FileSystemObject");
var objTextStream = objFileSys.GetFile(myFname).OpenAsTextStream(1, 0);
/*読み込みモードを使用、文字コードはUnicodeです。(Unicode文字が扱えるようにするため)*/

var data = new Array();   // 空の配列

// ファイルが最後まで読み込まれるまでループ  読み込み
while (objTextStream.AtEndOfLine==false) {
   data[i] = objTextStream.ReadLine();
   i++;
}

// 読み込み ここまで
// 解読 ここから

do{
 var my1 = data[j].indexOf("[" + mySname);
 j++;
}while(my1 == -1);   // 一行ずつ検索し、該当するセクションを探す
j--;

// 指定のセクションの内容の始まる行数(0から)を退避
var mySstert = j + 1;

// セクションの終わりを探す(先ほど先頭が見つかった行の次からスタート)
j++;
do{
 var my2 = data[j].indexOf("[");
 j++;
}while(my2 == -1);
j--;

// 指定セクションの最後の行を退避
mySend = j - 1;

// パラメータ名を検索
var my4 = mySstert;
do{
 var my6 = data[my4].substring(0, data[my4].indexOf("="));
 my4++;
}while(my6 != myPname);
my4--;

// コメント除去
var my3 = data[my4].indexOf(";");
if(my3 != -1){
 data[my4] = data[my4].slice(0, my3);
}

// 抽出
var Returndata = data[my4].substring(data[my4].indexOf("=") + 1);

// 得られた値を返す
return Returndata;

}   // function宣言終了

ソースをダブルクリックすると全選択ができます。もちろん普通に選択することも可能です。解説はスクリプト内のコメントで十分でしょう。


書式  :  myReadInI( セクション名,  パラメータ名, テキストファイルのパス );

戻り値  :  取得したパラメータの値が返ります。※半角数字は文字で返りますので数値を読み込みたいときはeval()を使ってください。

パラメータ

第1引数 必須
 セクションの名前です。[ ](角カッコ)は含みません。

第2引数 必須
 INIファイルのパラメータの名前です。

第3引数 必須
 INIファイルまでのパスです。絶対・相対どちらも指定可です。拡張子はなんでもかまいませんが、テキストファイルでかつ下に示す文法に従う、UTF-8のデータでなければなりません。


この関数で読み込めるINIファイルの文法を以下に示します。

  1. セクション名の前には空白文字を入れてもかまいません。
  2. コメントは;(セミコロン)から行末までで、途中からコメントとしても大丈夫です。
  3. 空行から先はすべてコメントです。そうしたくない場合は、その行を ; でコメントとしてください。
  4. 最後の行には必ず [ が含まれている必要があります。
  5. セクション名およびパラメータ名は@などの特殊文字で囲むことを推奨します。これは、先頭が一致する名前だと行を誤認識してしまうことがあるためです。(そのうち修正します)
5.の例
INIファイルの内容

[test]
userid=ユーザーID
user=ユーザー
[end]
このINIファイルに対して
myReadInI("test", "user", "test.ini");
とすると、3行目のuserよりも先に2行目のuseridにindexOfがヒットしてしまうためです。

使用例




Downlordボタンをクリックするとサンプルプログラムがダウンロードされます。セキュリティが不安な方はソースをみて安心してくださいな。また展開してからtest.iniを作成してください。「ファイルが見つかりません」エラーがでます。

次回のJavascriptでINIファイルを解読する その2に続きます。

0 件のコメント:

コメントを投稿

質問や意見などどしどしお寄せください!!