Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

BufferedReaderでのSI/SOの読み込み

BufferedReader(new FileReader("foo.dat"));
readLineを使用しfoo.datからレコードを取得しています。
ホストでの運用の為データの全角項目にはシフトIN・シフトOUT(0x0e/0x0f)が付加されています。
readLine時にSI/SOを含む形で読込む場合と含まない形で読込む場合があります。
調査した所レコードのバイト数もしくはレコード内の全角文字数が影響しているのではないかと思うのですが、確証はなく処理できないのです。
BufferedReaderでSI/SOが安定して読込む方法があれば御教授願います。

3

回答

6624

閲覧

3件の回答

評価

0

H社のホストからのレコードかなんかでしょうかね。
全角文字のフィールドが固定長の場合、SI/SOをつけていないのではないでしょうか?
ホストのプログラミングでは、けっこうありました。

readLine()による読み込みはやめて、
1. 0x0eが出てくるまで1バイトずつ読み込み、Stringに直す
2. 1バイト読み、0x0fなら次へ、違うならもう1バイト読み込み、最後にStringに直す
3. 残りを読み込んでStringに直す
ような、手作業になるかと思います(複数ある場合は2を繰り返すことになりますが)。

実レコードを受け取る前に、レコードの種類を特定できないのでしょうか。

評価

0

有難うございます。
しかし、固定長の場合もSO/SIは付加されています。
タブ区切り、固定長とも何らかの原因(組み合わさっているのかも)によりSO/SIが読込めたり読めなかったりするのです。
問い合わせた方がよさそうな気がしますね。
有難うございました。

評価

0

SI/SOがないだけで正常に読み取れるのだとすれば、以下のような感じでいいかも。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BufferedReaderSkipSISO {
    /** shift-inキャラクタ */
    private static final char SI = 0x0e;
    /** shift-outキャラクタ */
    private static final char SO = 0x0f;
    /** 内部のリーダ */
    BufferedReader _br = null;
    /**
     * コンストラクタ
     * @param fileName ファイル名
     * @throws IOException
     */
    public BufferedReaderSkipSISO(InputStreamReader isr) throws IOException {
        _br = new BufferedReader(isr);
    }
    /**
     * 通常の一行読み込み
     * @return 読み込んだ行
     * @throws IOException
     */
    public String readLine() throws IOException {
        return _br.readLine();
    }
    /**
     * SI/SOを除いた一行読み込み
     * @return 読み込んだ行
     * @throws IOException
     */
    public String readLineSkipSISO() throws IOException {
        StringBuffer sb = new StringBuffer(this.readLine());
        for (int i = sb.length() - 1; i >= 0; i--) {
            char c = sb.charAt(i);
            if (c == SI || c == SO) sb.delete(i, i + 1);
        }
        return sb.substring(0);
    }
    /**
     * クローズ処理
     * @throws IOException
     */
    public void close() throws IOException {
        _br.close();
    }
}
↓テストコード
import java.io.*;
public class TestReader {
    public static void main(String [] args) {
        BufferedReaderSkipSISO br = null;
        byte [] b = {(byte)0x41, (byte)0x42, (byte)0x0e, (byte)0x82, (byte)0x60, (byte)0x82, (byte)0x61, (byte)0x0f, (byte)0x43, (byte)0x44};

        try {
            br = new BufferedReaderSkipSISO(new InputStreamReader(new ByteArrayInputStream(b), "Shift_JIS"));
            System.out.println(br.readLineSkipSISO());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

本当はBufferedReaderを継承しようと思ったんですが、privateなメンバばかりなので却って面倒でした。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。