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

このQ&Aのポイント
  • 固定長データの情報処理について勉強中です。9byteの固定長データを入出力する方法について、(1) 1byteから2byteはそのまま入出力、(2) 3byte~7byteは10進数からゾーン10進数に変換、(3) バイナリ進数からゾーン10進数に変換する方法について知りたいです。
  • また、10レコードで90byteのデータを書き出す際の方法についてもアドバイスをいただきたいです。
  • 今後は数値変換についても勉強していく予定です。
回答を見る
  • ベストアンサー

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

現在情報処理についての勉強中ですが 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だった場合の 書き出し方法について情報処理について詳しい方いましたら アドバイスください。 なお数値変換については今後勉強していければと思っております。 どうぞよろしくお願い致します。

  • Java
  • 回答数4
  • ありがとう数2

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

> 元データの > (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); }

ITJack
質問者

お礼

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

その他の回答 (3)

  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.3

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

ITJack
質問者

お礼

どうもありがとうございます。 最後にご質問させてください。 たとえばですが 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置換したい プログラムを指示する場合 どのようにソースを書けばよいのでしょうか?? よろしくお願いします。

  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.2

> なお数値変換については今後勉強していければと思っております。 ということで,変換の仕方が今回の質問の要点ではないのなら, byte[] inbuf = new byte[9]; に対して,bis.read(inbuf, 0, 9) で9Bytesを読み込み, inbufを参照しながら byte[] outbuf = new byte[15]; に対して,数値変換の結果を書き出し, bos.write(outbuf, 0, 15) で15Bytesをファイル出力すればいいんじゃないですか。

ITJack
質問者

補足

アドバイスどうもありがとうございます。 数値変換に関しては、具体的に質問できるようになってから 新規で投稿できたらと思っております。 とりあえず数値変換は考えずに、 元データの (1)1byte~2byteで読みそのまま書き出す (2)3byte~7byteで読みそのまま書き出す (3)8byte~9byteで読みそのまま書き出す まだ数値変換の結果を書き出すまでは 先の話ですので 上記のような 配列?を領域を作っておきたいのです。 その後 (1)をそのまま出力 (2)数値変換 (3)数値変換 というような感じで配列ごとに管理できればと思っております。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

「1レコードが9byteで」って, 入力と出力でバイト数が変わるんだけどどっちの話? 全体としてはほぼバイトごとに処理すればいいだけなのでそんなに難しくなさそうな気がするんだけどなぁ. どこで困ってるんだろう.

ITJack
質問者

補足

今回の例題だけでご説明します。 入力時 1レコード9bye (1)  2bye→2bye (2)   5bye→10bye(Cを削る)→9bye (3)   2bye→4bye 出力時 1レコード15byeになります。

関連するQ&A

  • 固定長データのbyteスキップについて

    バイナリ入出力でご質問がございます。 下記の例のように各レコードにある 先頭5byte付与されたデータを スキップ(破棄)して 各レコード10byteずつ読み込みたいのですが なにかサンプルデータもしくは アドバイス頂けないでしょうか? どうぞよろしくお願い致します。 例 1レコード 10byte (先頭5byte付与) LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 LLLLL1234567890 ↓ 1234567890 1234567890 1234567890 1234567890 1234567890 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ 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[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • レコード長からのbyteスキップ設定について

    QNo.8229324から あらたに新規でご質問させて頂きます。 1レコードごとに10byteあったとします。 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 1234567890 レコード長からスキップ設定を35byteと設定したとします。 40byteごとに頭の付与された5byteをスキップさせたいのですが なにかサンプル及びアドバイス頂けますでしょうか? 仕様案 (1)まずはレコード先端の5byteをスキップ (2)次は35byteを超えた時点で5byteスキップを繰り返し。 どうぞ宜しくお願い致します。 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.io.ByteArrayOutputStream; public class dat{ 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[17]; int len = 0; while ((len = bis.read(buf, 0, 17)) == 17) { bos.write(buf, 0, 17); } bos.flush(); bos.close(); bis.close(); } catch(Exception e) { e.printStackTrace(); } }

    • ベストアンサー
    • Java
  • zipフォルダの解凍

    いつもお世話になっています。 zipフォルダ実行時のことで質問します。 指定のファイルをzipフォルダに格納して、フォルダ名を指定して格納することはできました。 それで、逆に、zipフォルダにどんなファイルがあるかを確かめたいと思ったのですが、可能なのでしょうか? zipフォルダに格納できたので、それを逆に変えてしようとしたのですが、いまいちわかりません。 zipフォルダに格納したソースは以下です。 import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipOutStream_Test { public static void main(String[] args) throws Exception { File zipf = new File("D:/zip_Java.zip"); //zipファイルに埋め込むfile名 File[] files = { new File("directory.txt") }; ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipf)); try { encode(zos,files); } catch (IOException e) { }catch(Exception e) { }finally { zos.close(); } } static byte[] buf = new byte[1024]; public static void encode(ZipOutputStream zos, File[] files) throws Exception { for(File f: files) { if(f.isDirectory() ) { encode(zos, f.listFiles() ); }else { ZipEntry ze = new ZipEntry(f.getPath().replace('\\', '/')); zos.putNextEntry(ze); InputStream is = new BufferedInputStream(new FileInputStream(f)); for (;;) { int len = is.read(buf); if (len < 0) break; zos.write(buf, 0, len); } is.close(); } } } } 宜しくお願いします。

    • ベストアンサー
    • Java
  • strutsでファイルダウンロード(WinでOK,linuxでNG)

    strutsでWindowsのexeファイルのダウンロードを実装しましたが、Windows上のtomcatにdeployすると正常にダウンロードできるのに、linux(fedora-core3)上のtomcatにdeployすると、ダウンロードしたファイルがhtmlになってしまいます。 hoge.exeという名前のファイルはダウンロードできるのですが、それが実はテキストで、メモ帳で開くと、ダウンロード画面のhtmlが表示されます。 この状況は何によって生み出されているのでしょうか。 お分かりになる方、ヒントをお願いいたします。 以下にファイルダウンロード部のソース(抜粋)を掲載させていただきます。 ----- 以下ソース ----- protected void download(HttpServletResponse response, String fileType, String filename) { try { // exeファイルのダウンロード時 if (fileType.equals("application/octet-stream")) { response.setHeader("Content-Disposition", "attachment; filename=" + filename); } response.setContentType(fileType); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename)); BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); byte[] buf = new byte[128]; int size; while ((size = bis.read(buf, 0, buf.length)) != -1) { bos.write(buf, 0, size); } bos.close(); bis.close(); } catch (IOException e) { throw new thisSystemException("could not send file[" + filename + "]"); }

    • ベストアンサー
    • Java
  • 入出力(FileOutputStreamについて)

    以下のコードは独習Javaのコードです。これを実行すればテキストに0~11までの数字が書き込まれるはずなのですが・・・なぜかA~Hが横に並んで書き込まれてます。 どうなってるのかどなたか教えてください。 import java.io.*; class BufferedOutputStreamDemo {  public static void main(String args[])  {   try   {    FileOutputStream fos = new FileOutputStream(args[0]);    BufferedOutputStream bos = new BufferedOutputStream(fos);    for(int i = 0; i <12; i++)    { bos.write(i);    } bos.close();   }   catch(Exception e)   {     System.out.println("Exception : " +e);   }  } }

    • ベストアンサー
    • Java
  • ObjectInputStreamとStreamCorruptedExceptionについて

    このようなソースがあり ------------------------------------------------- import java.io.File; import java.io.FileInputStream; import java.io.ObjectOutputStream; import java.io.ObjectInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.BufferedInputStream; import java.io.Serializable; import java.io.ByteArrayInputStream; public class TTT{ public static void main( String[] args ){ try{ FileInputStream fis = new FileInputStream( "C:\\aa\\ddd.txt" ); //FileInputStream fis = new FileInputStream( "C:\\aa\\aa.jpg" ); ObjectInputStream ois = new ObjectInputStream( fis ); }catch( Exception w ){ w.printStackTrace(); } } } ------------------------------------------------- これをコンパイルをかけて実行すると java.io.StreamCorruptedException: invalid stream header at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:737) at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253) at TTT.main(TTT.java:24) となってしまいます。 読み込むファイルをコメント部分の画像ファイルに 変えてみても同様です。 StreamCorruptedExceptionの内容はJAVAのAPIドキュメントでは読み込まれた制御情報が、内部整合検査に違反した場合にスローされると説明がありますがこれはどういう意味でしょうか? また正しく実行させるにはどのようにすればいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • バイナリファイルの読み込み方

    バイナリファイルの中身を解析したいと思っています。 「先頭の3バイトは日付、次の2バイトはファイルサイズ、 さらに次の4バイトはファイル種類が格納」というようにファイルのフォーマット が定まっている場合、どのように読み込めばよいでしょうか。 下記のコードを改変してできないかと思っています。 import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class BinaryRead { public static void main(String[] args) { BufferedInputStream bi = null; int tmp=0; try { //インスタンス生成 bi = new BufferedInputStream(new FileInputStream("hoge.dat")); //ストリームの終わりに達した場合は-1 while((tmp=bi.read())!=-1){ System.out.println(tmp); } } catch (Exception e){ e.printStackTrace(); } finally { //入力ストリームを閉じる bi.close(); } } }

    • ベストアンサー
    • Java
  • Zipファイル解凍処理について

    こんにちわ。 Javaの解凍処理について質問です。 Test.zipがあって、その中身が「テスト.xls」とした時、うまく解凍ができません。 Zipファイルの中身が日本語名ではなく、「Test.xls」であれば正常に解凍ができます。 下記の書き方では日本語名のファイルの入ったZipファイルを解凍することはできないのでしょうか? どなたかご教授お願い致します。 String fname = null; FileInputStream fis = null; BufferedInputStream bis = null; ZipInputStream zis = null; ZipEntry zent = null; FileOutputStream fos = null; try { fis = new FileInputStream(FilePath); bis = new BufferedInputStream(fis); zis = new ZipInputStream(bis); byte[] buf = new byte[1024]; int len; // アーカイブ中に含まれるファイル情報の取得 while ((zent = zis.getNextEntry()) != null) { int intResult = zent.toString().indexOf("."); int intLength = zent.toString().length(); //ファイル名の変更(フォルダ名+社員コード)StringBuffer BuffRename = new StringBuffer(); BuffRename.append("D:\\test\\"); BuffRename.append(zent.getName().substring(0,intResult)); BuffRename.append(SyainCd); BuffRename.append(zent.getName().substring(intResult,intLength)); fname = BuffRename.toString(); //書き込みファイルをオープン fos = new FileOutputStream(fname); while (-1 != (len = zis.read(buf, 0, buf.length))) { fos.write(buf, 0, len); } //★★★ fos.close(); } Catch・finallyは省略

  • Servletで画像を表示させたい時。

    例えばdocBaseがtestで、test直下にlogoフォルダがあって、その中に foobar.jpgと言う画像ファイルがあった場合、次のソースコードで出るはずなのですが、 /* イメージ画像の表示 */ package srd; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class dispLogo extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("image/jpeg"); BufferedInputStream bis = new BufferedInputStream(new FileInputStream("\\usr\\local\\test\\logo\\foobar.jpg")); ServletOutputStream out = res.getOutputStream(); int n; byte[] buf = new byte[512]; while ((n = bis.read(buf)) != -1) { out.write(buf, 0, n); } bis.close(); } } どうしても、画像のあるパスが分からないというエラーメッセージがでてしまいます。 画像はtmpフォルダに入れるべきなのでしょうか。それでも上手く表示されません。 どなたか分かる方がいましたら、教えてください。

  • ファイル読み込み/書き込み速度を上げるには

    下記のようなファイルの読み込み/書き込み処理において、もっと効率よく(速く)読み込み・書き込みをしたい場合どのような工夫をすれば良いでしょうか? BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("sample2.data")); BufferedInputStream in = new BufferedInputStream(new FileInputStream("sample1.data")); int c ; while((c = in.read()) != -1) { out.write(c); } in.close(); out.flush(); out.close();

    • ベストアンサー
    • Java

専門家に質問してみよう