こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

固定長データの情報処理について

現在情報処理についての勉強中ですが
import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;


public class dat_stream {

public static void main(String[] args) {

// 読み込むファイルの名前
String inputFileName = "ファイル名";

// 書き込むファイルの名前
String outputFileName = "ファイル名";

// ファイルオブジェクトの生成
File inputFile = new File(inputFileName);
File outputFile = new File(outputFileName);

try {
// 入力ストリームの生成
FileInputStream fis = new FileInputStream(inputFile);
BufferedInputStream bis = new BufferedInputStream(fis);

// 出力ストリームの生成
FileOutputStream fos = new FileOutputStream(outputFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);

// 読み込み用バイト配列
byte[] buf = new byte[9];

// ファイルへの読み書き
int len = 0;
while ( ( len = bis.read(buf) ) != -1 ) {
bos.write(buf, 0, len);
}

// 後始末
bos.flush();
bos.close();
bis.close();

// エラーがあった場合は、スタックトレースを出力
} catch(Exception e) {
e.printStackTrace();
}

}

}
を使用してDATデータの入出力を考えています。

F0 F2 12 34 56 78 9C 00 50といった9byteの固定長データが
あったとします。


(1)1byteから2byteはそのまま入出力
F0 F2 →F0 F2

(2)3byte~7byteパック10進数からアンパック(ゾーン)10進数に変換
12 34 56 78 9C →F1 F2 F3 F4 F5 F6 F7 F8 F9
こちらに関しては上位桁・下位桁で計算し正の数・負の数等も
考えなければいけないと思うのですが・・・

(3)バイナリ進数からゾーン10進数に変換
00 50→F0 F0 F8 F0

計算方法)0*16進数3剰 + 0*16進数2剰 + 5*16進数1剰+ 0

このような(1)~(3)のようなバイナリ入出力を考えた場合
1レコードが9byteで
10レコードで90byteだった場合の
書き出し方法について情報処理について詳しい方いましたら
アドバイスください。
なお数値変換については今後勉強していければと思っております。
どうぞよろしくお願い致します。

投稿日時 - 2012-12-27 11:08:47

QNo.7863616

困ってます

質問者が選んだベストアンサー

> 元データの
> (1)1byte~2byteで読みそのまま書き出す
> (2)3byte~7byteで読みそのまま書き出す
> (3)8byte~9byteで読みそのまま書き出す

これだと、書き出し側も9byte単位になって、本来やりたいはずの15byte単位になりませんよ。
変換を後回しにするにしても、出力byte数は揃えておいた方がいいのでは?

出力内容を変更したいなら、#2にある「出力用バッファ」を用意するのが常套手段でしょう。

#2,#3さんのコードを借用して、効率無視で作れば

while ((len = bis.read(inbuf, 0, 9)) == 9) {
// (1) 2バイトをそのまま
outbuf[0] = inbuf[0] ;
outbuf[1] = inbuf[1] ;
// (2) 5バイトをそのまま
outbuf[2] = inbuf[2] ;
outbuf[3] = inbuf[3] ;
outbuf[4] = inbuf[4] ;
outbuf[5] = inbuf[5] ;
outbuf[6] = inbuf[6] ;
// (2)' 最終的に9byte使うので残りbyte分の空き
outbuf[7] = 0 ;
outbuf[8] = 0 ;
outbuf[9] = 0 ;
outbuf[10] = 0 ;
// (3) 2バイトをそのまま
outbuf[11] = inbuf[7] ;
outbuf[12] = inbuf[8] ;
// (3)' 最終的に4byte使うので残りbyte分の空き
outbuf[13] = 0 ;
outbuf[14] = 0;

bos.write(outbuf, 0, 15);
}

あるいは、#3に近い形なら
while ((len = bis.read(inbuf, 0, 9)) == 9) {
// (1) 2バイトをそのまま
byte[] outbuf1=new byte[2] ;
outbuf1[0] = inbuf[0] ;
outbuf1[1] = inbuf[1] ;
bos.write(outbuf1);
// (2) 5バイトをそのまま
byte[] outbuf2=new byte[9] ;
outbuf2[0] = inbuf[2] ;
outbuf2[1] = inbuf[3] ;
outbuf2[2] = inbuf[4] ;
outbuf2[3] = inbuf[5] ;
outbuf2[4] = inbuf[6] ;
// (2)' 最終的に9byte使うので残りbyte分の空き
outbuf2[5] = 0 ;
outbuf2[6] = 0 ;
outbuf2[7] = 0 ;
outbuf2[8] = 0 ;
bos.write(outbuf2);
// (3) 2バイトをそのまま
byte[] outbuf2=new byte[4] ;
outbuf3[0] = inbuf[7] ;
outbuf3[1] = inbuf[8] ;
// (3)' 最終的に4byte使うので残りbyte分の空き
outbuf3[2] = 0 ;
outbuf3[3] = 0;
bos.write(outbuf3);
}

投稿日時 - 2012-12-29 11:54:56

お礼

返信遅くなりました。
アドバイスどうもありがとうございます。
あらかじめ、領域を作ったほうが、後々作業しやすいのですね。
とりあえず領域を9byteから15byteにすることが出来ました。
byte型でのwriteメソッドの扱いがよくわからないのですが
色々とやってみます。
どうもありがとうございました。

投稿日時 - 2012-12-31 15:45:40

ANo.4

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.3

while ((len = bis.read(buf, 0, 9)) == 9) {
bos.write(buf, 0, 2);
bos.write(buf, 2, 5);
bos.write(buf, 7, 2);
}

投稿日時 - 2012-12-28 14:32:26

お礼

どうもありがとうございます。
最後にご質問させてください。
たとえばですが
bos.write(buf, 0, 2);//配列1
bos.write(buf, 2, 5);//配列2
bos.write(buf, 7, 2);//配列3としたとき

配列2のbos.write(buf, 2, 5);の1byte目を00置換したい
プログラムを指示する場合
どのようにソースを書けばよいのでしょうか??
よろしくお願いします。

投稿日時 - 2012-12-29 02:04:23

ANo.2

> なお数値変換については今後勉強していければと思っております。

ということで,変換の仕方が今回の質問の要点ではないのなら,

byte[] inbuf = new byte[9];
に対して,bis.read(inbuf, 0, 9) で9Bytesを読み込み,
inbufを参照しながら
byte[] outbuf = new byte[15];
に対して,数値変換の結果を書き出し,
bos.write(outbuf, 0, 15) で15Bytesをファイル出力すればいいんじゃないですか。

投稿日時 - 2012-12-27 22:54:23

補足

アドバイスどうもありがとうございます。
数値変換に関しては、具体的に質問できるようになってから
新規で投稿できたらと思っております。

とりあえず数値変換は考えずに、

元データの
(1)1byte~2byteで読みそのまま書き出す
(2)3byte~7byteで読みそのまま書き出す
(3)8byte~9byteで読みそのまま書き出す

まだ数値変換の結果を書き出すまでは
先の話ですので
上記のような
配列?を領域を作っておきたいのです。


その後
(1)をそのまま出力
(2)数値変換
(3)数値変換
というような感じで配列ごとに管理できればと思っております。

投稿日時 - 2012-12-28 09:40:35

ANo.1

「1レコードが9byteで」って, 入力と出力でバイト数が変わるんだけどどっちの話?

全体としてはほぼバイトごとに処理すればいいだけなのでそんなに難しくなさそうな気がするんだけどなぁ. どこで困ってるんだろう.

投稿日時 - 2012-12-27 13:21:12

補足

今回の例題だけでご説明します。

入力時 1レコード9bye

(1)  2bye→2bye

(2)   5bye→10bye(Cを削る)→9bye

(3)   2bye→4bye

出力時 1レコード15byeになります。

投稿日時 - 2012-12-27 13:55:01

あなたにオススメの質問