はじめに
【COBOL(Common Business Oriented Language) = コボル】と
【Java = ジャバ】を比較してみました。
COBOLの基本的な記載方法は以下を参照。
データ転記
cobol
**************************************************************************
03 END-FLG PIC X(3).
*文字定数転記処理
MOVE "END" TO END-FLG.
java
//クラス※1
public class Example {
/*public: アクセス修飾子で、このクラスがどこからでもアクセス可能*/
/*class: クラスを定義するためのキーワード*/
/*Example: クラスの名前です。クラス名は、通常は大文字で始める*/
// COBOLのEND-FLGをJavaで表現
private String endFlg;
/* フィールド宣言※2 で endFlg を3文字の文字列として宣言 */
// コンストラクタ
public Example() {
this.endFlg = "";
}
/* コンストラクタ※3で endFlg を初期化 */
// getterメソッド
public String getEndFlg() {
return endFlg;
}
/* getterメソッド※4、※5で endFlg の値を取得 */
// setterメソッド
public void setEndFlg(String endFlg) {
/* void: このメソッドが何も値を返さないことを示す */
/* setEndFlg(String endFlg): メソッドの名前です。
引数endFlgでフィールドendFlgの値を設定します。 */
//条件分岐 endFlg が NULL かつ 3文字以下なら
if (endFlg != null && endFlg.length() <= 3) {
//条件分岐 endFlg が NULL かつ 3文字以下なら
this.endFlg = endFlg;
/* this.endFlg = endFlg;: フィールドendFlgに引数のendFlgの値を設定します。*/
} else {
throw new IllegalArgumentException("endFlg must be a string with a maximum length of 3 characters.");
}
}
/* setterメソッド で endFlg の値を設定 6※~8※ */
// テスト用のmainメソッド
public static void main(String[] args) {
/* main: メソッドの名前です。Javaプログラムのエントリーポイント(プログラムの実行開始地点)として、この名前は特別な意味を持ちます。*/
/* String[] args: コマンドライン引数を受け取るためのパラメータです。*/
Example example = new Example();
/* Exampleクラスのインスタンスを作成します。*/
example.setEndFlg("END");
/* 作成したExampleインスタンスのsetEndFlgメソッドを呼び出して、endFlgフィールドに"END"を設定します。*/
System.out.println("End Flag: " + example.getEndFlg());
/* System: Javaの標準ライブラリのクラスです。*/
/* out: Systemクラスの標準出力ストリームです。*/
/* println: 標準出力ストリームに文字列を表示し、改行を行うメソッドです。*/
}
/* mainメソッド 9※、10※ */
}
※2 【Java】フィールド変数
※3 コンストラクタとは
※4 【Java】getter・setterのメモ
※5 (オブジェクト指向における) getter/setter メソッドの使いどころ
※6 java 条件式とif文
※7 可読性を高めるif文の書き方-java
※8 【Java】throwとthrowsの使い方を簡潔に説明してみる
※9 【Java】this について
※10 【Java】Public static void main(String[] args)の意味
制御構造
cobol
PERFORM UNTIL・・・ループを開始する構文です。
このループは指定された条件が満たされるまで繰り返し実行されます。
PERFORM UNTIL END-FLG = "END" OR WK-COUNT > 99
・・・ ループを終了する条件です。
ND-FLGが"END"と等しい か、
WK-COUNTが99を超えると
ループが終了します。
READ IN-FILE
・・・入力ファイルIN-FILEからレコードを読み取ります。
AT END
⇒ 入力ファイルの終端に達した場合に実行されるセクションです。
MOVE "END" TO END-FLG
NOT AT END
⇒ 入力ファイルの終端に達した場合に実行されるセクションです。
MOVE IN-FILE-REC TO OUT-FILE-REC
・・・入力ファイルのレコードを出力ファイルのレコードにコピーします。
WRITE OUT-REC
・・・WRITE OUT-REC: 出力ファイルにレコードを書き込みます。
ADD 1 TO WK-COUNT
・・・ADD 1 TO WK-COUNT: カウンター変数WK-COUNTに1を加算します。
END-READ
・・・ READステートメントの終了を示します。
END-PERFORM.
・・・ PERFORMステートメントの終了を示します。
なお 前提として、
IO-FILEという論理ファイル名を物理ファイル"text01.txt"に割り当てます。
ファイルの組織は行順序(LINE SEQUENTIAL)です。
⇒ファイルの各レコードが1行のデータである可変長のレコードで構成され、復帰文字(CR)または改行文字(LF)で終了することを意味しています。
OUT-FILEという論理ファイル名を物理ファイル"text02.txt"に割り当てます。
ファイルの組織は順編成(SEQUENTIAL)です。
⇒レコードの終端に改行コードがないファイル
END-FLG: 3文字のフラグ変数。
WK-COUNT: 2桁のカウンター変数。
IN-FILE-REC: 入力ファイルのレコードを保持する変数。長さは80文字です。
OUT-FILE-REC: 出力ファイルのレコードを保持する変数。長さは80文字です。
java
/* ファイルの読み書きと例外処理のパッケージをインポート */
import java.io.BufferedReader;
//ファイルから行単位で効率的に文字データを読み取る
import java.io.BufferedWriter;
//ファイルに行単位で効率的に文字データを書き込む
import java.io.FileReader;
//ファイルから文字データを読み取るために使用
import java.io.FileWriter;
//ファイルに文字データを書き込むために使用
import java.io.IOException;
//入出力操作でエラーが発生した場合にスローされる例外
/* メインクラス */
public class FileProcessingExample {
/* メインメソッド */
public static void main(String[] args) {
String endFlg = ""; //終了フラグ
int wkCount = 0; //カウンタ変数
final int RECORD_LENGTH = 80; // レコードの長さを定義する定数
// * レコードの長さ(80文字)を定義する定数 *//
/* 例外処理のための try ブロックを開始※10
try-with-resources 構文を使用して、リソースが自動的に閉じられるようにします。※11 */
try (BufferedReader inFile = new BufferedReader(new FileReader("text01.txt"));
BufferedWriter outFile = new BufferedWriter(new FileWriter("text02.txt", true))) { // trueで追記モードにする
/* FileReader を使って、text01.txt ファイルを読み取るための inFile を作成 */
/* FileWriter を使って、text02.txt ファイルに書き込むための outFile を作成します。
FileWriter のコンストラクタに true を渡すことで、出力ファイル (text02.txt) に追記モードで開きます。
これにより、既存の内容を消去せずに新しいデータを追加することができます。*/
StringBuilder inFileRec = new StringBuilder(RECORD_LENGTH); // 長さ80のStringBuilderを使用
/* StringBuilder: 可変長の文字列を扱うために使用します。 */
String line;
while (!endFlg.equals("END") && wkCount <= 99) {
/* while ループを開始します。このループは endFlg が "END" に等しくない、
かつ wkCount が99以下の間繰り返されます。 ※13 */
// ファイルから1行読み取る
line = inFile.readLine();
if (line == null) {
endFlg = "END";
} else {
// 読み取った行が80文字未満の場合は、スペースで埋める
inFileRec.setLength(0); // StringBuilderをクリアして新しいレコードを処理
inFileRec.append(line); // 読み取った行を StringBuilder に追加
/* レコードが80文字未満の場合、残りの部分をスペースで埋めます。 */
if (inFileRec.length() < RECORD_LENGTH) {
//レコードが80文字未満の場合 for文を使う ※13
/* ループ変数 i を初期化します。i の初期値として inFileRec.length() を設定しています。
これは、現在の StringBuilder の長さを取得し、その値を i に設定することを意味します。*/
/* i が RECORD_LENGTH (ここでは80)より小さい間、ループが実行されます。
つまり、inFileRec の長さが80文字未満の間はループが続きます。*/
for (int i = inFileRec.length(); i < RECORD_LENGTH; i++) {
inFileRec.append(' '); // スペースで埋める
}
}
// レコードを書き込む
outFile.write(inFileRec.toString());
//改行コードは追加しないことで、データが順編成でそのまま書き込まれます。
wkCount++;
/* wkCount を1増加 */
}
}
} catch (IOException e) {
/ * IOException が発生した場合の例外処理を行います */
e.printStackTrace(); //スタックトレースを出力し、例外の詳細を表示します。
}
}
}
※11 Javaの例外処理について
※13 [Java]ループ処理について
型とかを厳密に考えると非常に大変なため、
関連した情報(抜粋:COBOLプログラムを忠実に移植するとなると、COBOLの計算の癖を丁寧に拾って再現させていかなければなりません。読みづらいし、なぜこうしなければならないか説明しづらいソースになります。仕様を当世風に合わせて再定義できればいいんですけど、「動きが変わると困る」とか言われてしまうと大変ですね。)
や、関連しそうでしないかも(紹介の仕方が正しくないだけ)情報・その他のトピックのご紹介だけ。
decimal型があるからCOBOLもう要らんやろ、という件について(あるいは十進演算の話)