2011.06.22
 

大量のスペースをスキャンする

Question

サード・パーティーのクエリー・ツールで作成されたクエリーの保存に使用している多数の (約 1,200) ユーザー・スペースがあります。その一部は QDLS パスを使用しており、それらのクエリーを識別し、代わりに IFS ディレクトリーを使用するよう変更するのにかなりの負担が掛かりました。これらのユーザー・スペース中の文字列「QDLS」をどのように探せばいいのでしょうか。QShell で grep ツールを試してみましたが、行当たり 2,048 文字しか検索できないため、これらのユーザー・スペースの文字列は検索できません。助けてください。

Answer

ユーザー・スペースまたは IFS ストリーム・ファイル中の文字列を検索できる、RPG で作成された QShell ユーティリティーのコードを提供しましょう。また、QShell でそれをどのように呼び出し、検索するユーザー・スペースの名前を提供するのかお見せしましょう。

間に合わせのソリューションとしては、自分の QShell ユーティリティーを作成することです。QShell を利用する主な理由は、ファイル名を見つけるのに役立つからです。これが単発のプログラムでない場合は、パフォーマンス上の理由で他の方法を選択したかもしれませんが。

ディスプレイ・ファイルを使用していないという前提で、QShell から任意の *PGM オブジェクトを呼び出すことができるという考えがベースです。私の例では、FINDQDLS というプログラムを作成しています。したがって、そのプログラムが MYLIB ライブラリーにあるという前提で、次のように QShell から呼び出すことができます。

> /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM

これは、QShell 内から私の FINDQDLS プログラムを実行しており、パラメーターは渡しません。

ある IFS ディレクトリー内のパターン *.txt に一致するファイルごとに 1 回ずつ、これを何回も実行したいとしましょう。そのためには、QShell から次を実行できます。

> for f in *.txt; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM "$f"; done

この例では、パターン「*.txt」に一致するファイルごとに MYLIB/FINDQDLS を実行させて、ファイル名をパラメーターとして渡すよう QShell に指示しています。私の IFS ディレクトリーに *.txt で終わるファイルが 200 件ある場合、FINDQDLS プログラムを 200 回呼び出します。それぞれ、異なるファイル名がパラメーターとして渡されます。

IFS では、*USRSPC オブジェクトを、ストリーム・ファイルの場合とまったく同じに使用できます。そのため、自分のプログラムを呼び出したいが QShell に IFS パス名を USRSPCLIB ライブラリーのすべてのユーザー・スペースに渡させる場合、次のようにできます。

> for f in /QSYS.LIB/USRSPCLIB.LIB/*.USRSPC; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM "$f"; done

注: /QSYS.LIB パス名を使用して名前ライブラリー/オブジェクト・ファイル・システムにアクセスする場合、パス名をすべて大文字で入力しないと QShell の結果がおかしくなることがわかりました。そのため、ネイティブ・オブジェクトを使用している場合、パス名はすべて大文字にします。

前述の例では、USRSPCLIB ライブラリーのユーザー・スペースごとに 1 回 MYLIB/FINDQDLS を呼び出しています。毎回 IFS パス名がユーザー・スペースに渡されています。

FINDQDLS は、ストリーム・ファイルまたはユーザー・スペース・オブジェクト中の「QDLS」文字列を検索するために作成したプログラムです。この記事の終わりに、ソース・コードをダウンロードできるリンクを用意しました。プログラムの理解に役立つよう、処理内容を説明する擬似コードをいくつかご紹介します。

  • 第 1 パラメーターからパス名を取得します。
  • IFS open() API でパス名を開きます-- 必要に応じて EBCDIC へテキスト変換を行います。
  • fstat() API を使用して、開いたファイルのサイズを取得します。
  • ファイルのデータすべてを格納できるよう十分なメモリーをバッファーに割り当てます。
  • ファイル全体をバッファーに読み込みます。
  • IFS ファイルを閉じると、データのコピーが準備されます。
  • 検索で大文字小文字を区別するよう、バッファーを大文字に変換します。
  • ScanMem() プロシージャーを呼び出してバッファーを検索します。(このプロシージャーは既に持っていたもので、C API を使用して、メモリーの大部分中のある文字列を検索します。)
  •     
  • 文字列が見つかったら、ファイル名を印刷します。
  • 割り当てられていたメモリーを解放します。
  • プログラムを終了します。

上記のように、約 16MB 以下のファイルのみ処理します。いずれにしても、このサイズがユーザー・スペースの最大サイズです。しかし、多少変更すれば、大規模ファイル向けにテラスペースを処理できるようになります。そのため、一部の STMF オブジェクトのサイズが 16MB より大きな IFS ディレクトリーで実行する場合、「Not enough memory for this object (このオブジェクトにはメモリーが足りません)」というエラーを受信する場合があります。

このプログラムを MYLIB に入れると、上記のように実行でき、文字列「QDLS」を含むオブジェクトのリストが印刷されます。

> for f in /QSYS.LIB/USRSPCLIB.LIB/*.USRSPC; do /QSYS.LIB/MYLIB.LIB/FINDQDLS.PGM "$f"; done
  /QSYS.LIB/USRSPCLIB.LIB/TESTUSRSPC.USRSPC
  /QSYS.LIB/USRSPCLIB.LIB/ANOTHER.USRSPC
$

FINDQDLS プログラムのソースは systeminetwork.com/article/scanning-slew-spaces からダウンロードできます。ページの下部にスクロールしてください。

ページトップ

ボタン