テキストファイルを16進数で読み込む - 萌えJava超入門
テキストファイルを読み込む

テキストファイルを
16進数で読み込む

ファイルの文字列を 16進数として解釈して、int配列に読み込みます。

目次

1. 目的


萌えJava超入門
そう、目的よね。
16進数の文字列が
テキストファイルに書いてあるのって
レアじゃない?
萌えJava超入門
そうなんだけどさ。前に
「ダンジョン探索プログラム」
って作っただろ?
あのマップをファイルから
読み込みたいんだよ。
萌えJava超入門
あ~。16進数使ったわね。
それはあなたの欲望に
付き合えってこと?
萌えJava超入門
会長って16進数
好きっスよね。
萌えJava超入門

萌えJava超入門
このマップを
ファイルから
読み込みたいのだ。

このページでは、ダンジョンのマップを表した16進数の3次元配列を
テキストファイルから読み込んで表示させてみましょう。



2. マップのテキストファイル作成

マップのひとマスを intで表した仕様で、酔狂にも16進数として扱いました。
これをそのままテキストファイルにします。
萌えJava超入門 萌えJava超入門
すっ...
酔狂はないだろ。
萌えJava超入門

萌えJava超入門 萌えJava超入門
floor01.txt って
一見CSVファイルかと思ったけど
拡張子が「.txt」ね?
萌えJava超入門
中身は完全に CSVファイルだ。
拡張子なんて飾りだよ。
Linuxユーザーの真夜は
良く知ってるだろ?
暴言。
拡張子だってがんばっているんです。

以下の2つのファイルを、ワークスペース(例では wsディレクトリ)に保存してください。
このファイルを読み込みます。

  1001,1010,1010,1100,1001,1000,1000,1110,1101,61101
  0101,1011,1110,0101,0011,0010,0110,1001,0110,0101
  0011,1000,1010,0020,1010,1000,1010,0100,1111,0101
  1101,0101,1001,2100,1101,0101,61101,0011,521210,0112
  0111,0101,0011,0110,0101,0101,0211,a41102,1111,1101
  1001,0010,1100,1001,0100,0201,451112,0201,1012,0100
  0101,1101,0101,0011,0110,0101,1011,0010,1100,0101
  220201,0102,0101,1011,1010,0110,1011,1110,0101,0101
  0101,0111,0011,1010,351110,b31021,1010,1010,0110,0101
  0011,1010,1010,151110,71011,c52110,451011,1010,1010,0110

  351101,1011,1100,1001,1010,1010,1100,1011,1110,71101
  0011,1100,0111,0101,1001,1100,0011,1010,521200,0112
  1111,0001,1010,0100,0001,0010,1010,1100,0101,1101
  1011,0110,1111,0101,0111,1101,71101,0111,0101,0101
  1101,1001,1200,0002,1010,0100,0211,a41102,0101,0101
  0201,0012,0110,0111,1111,0011,1010,0110,0101,0111
  0011,1100,951121,1101,651121,1001,1000,1010,0010,1100
  1101,0011,2020,0000,2020,0000,0100,1011,1110,0101
  0011,1100,852111,0101,752111,0001,0010,1010,1010,0100
  1111,0011,1010,0010,1010,0110,1011,1010,1110,0111

ダウンロードの際に「.csv」拡張子は面倒が起こりやすいので、
このチュートリアルでは、Excelで開く予定がなさそうな場合に限って
拡張子を「.txt」としてお届けする場合があります。
ご容赦ください。



3. 16進数文字列をintに変換する

java.lang.Integer
   class Integer

Integerクラスの parseIntメソッドが再登場です。
以前にもご紹介させていただいたメソッドですが、
オーバーロードで引数違いの書式が出てきたので改めて紹介させていただきます。

ご参照↓
 第二十章 ラッパークラスで文字列を数値に変換する
   parseXxxメソッドを使った変換




萌えJava超入門
これは前にでてきたやつね?
書式1
int num = parseInt(String s)
第一引数の数値文字列を、十進法で解釈して intで返します。
つまり、 文字列 "10" を、数値の 10 に変換します。

例外
java.lang.NumberFormatException
引数が適切な数値形式でない場合に発生します。
非チェック例外です。必ずしも例外処理を記述する必要はありません。



萌えJava超入門
こっちが新しいやつだ。
radix を「16」とすれば、
文字列「s」が16進数であるものとして
intに変換する。
書式2
int num = parseInt(String s, int radix)
第一引数の数値文字列を、第二引数の進数法で解釈して intで返します。
つまり、第二引数が16の場合は、文字列を16進数と解釈して
"b" を、数値の 11 に変換します。

例外
java.lang.NumberFormatException
引数が適切な数値形式でない場合に発生します。
非チェック例外です。必ずしも例外処理を記述する必要はありません。

ご参照↓
 16進数

萌えJava超入門
なるほど。


4. マップを読み込む

3次元配列に、2フロア分のマップを読み込みます。
Sample07_01 で実際にファイルの内容を読み込めているか、配列の中身を表示させてみましょう。

Sample07_01.java と ReadFile_04.java を floor01.txt、floor02.txt と同じフォルダに保存して実行してください。

//Sample07_01.java

import java.io.File;

class Sample07_01{
  public static void main(String[] args){

      String[] mapPaths = {
          "floor01.txt", //1階のマップ
          "floor02.txt"  //2階のマップ
      };
      int[][][] map3D = new int[mapPaths.length][][];

      //16進数として読込
      for(int i=0; i<mapPaths.length; i++){
          map3D[i]
          = ReadFile_04.toIntArray2D(new File(mapPaths[i]), "UTF-8", ",", 16);
      }

      //表示
      for(int i=0; i<map3D.length; i++){
          System.out.println(mapPaths[i]);
          if(map3D[i] != null){
            for(int j=0; j<map3D[i].length; j++){
                for(int k=0; k<map3D[i][j].length; k++){

                    System.out.printf("%06x ", map3D[i][j][k]);
                }
                System.out.println();
            }
              System.out.println("end");
          }else{
              System.out.println("null");
          }
          System.out.println();
      }
  }

}

System.out.printf("%06x ", map3D[i][j][k]);
   flags 0
   width 6
   conversion x
「0埋め6桁の16進数で表示」の意。

 ご参照↓
Java超入門
 第十八章 Stringクラス formatメソッド

萌えJava超入門
toIntArray2Dメソッドが
オーバーロードになっている。
メソッド内部で引数違いの
同じメソッドを呼んでいるぞ。
これもよく使う書き方だ。
//ReadFile_04.java

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

class ReadFile_04{

  /*何進数か指定しない場合は10進数として処理*/
  public static int[][] toIntArray2D(
              File inputFile,
              String encoding,
              String delimiters
  ){
      return toIntArray2D(inputFile, encoding, delimiters, 10);
  }

  /*何進数か指定できるオーバーロード*/
  public static int[][] toIntArray2D(
              File inputFile,
              String encoding,
              String delimiters,
              int radix
  ){
      int[][] array2D = null;

      ArrayList<String> list = fileToList(inputFile, encoding);

      if(list!=null){
          array2D = new int[list.size()][];
          for(int i=0; i< list.size(); i++){
              String[] strArray = list.get(i).split(delimiters);
              int[] intArray = new int[strArray.length];
              try{
                  for(int j=0; j< strArray.length; j++){
                      //要素を一つずつ intに変換
                      intArray[j] = Integer.parseInt(strArray[j], radix);
                  }
                  array2D[i] = intArray;//一次元配列を二次元配列の要素として代入
              }catch(NumberFormatException e){
                  e.printStackTrace();
                  return null;
              }
          }
      }else{
          return null;
      }
      return array2D;
  }

  public static ArrayList<ArrayList<String>> toStringList2D(
              File inputFile,
              String encoding,
              String delimiters
  ){
      ArrayList<ArrayList<String>> List2D = null;

      ArrayList<String> list = fileToList(inputFile, encoding);
      if(list!=null){
          List2D = new ArrayList<ArrayList<String>>();
          for(int i=0; i< list.size(); i++){
              String[] line = list.get(i).split(delimiters);
              List2D.add(new ArrayList<String>(Arrays.asList(line)));
          }
      }else{
          return null;
      }
      return List2D;
  }

  public static String[][] toStringArray2D(
              File inputFile,
              String encoding,
              String delimiters
  ){
      String[][] array2D = null;

      ArrayList<String> list = fileToList(inputFile, encoding);
      if(list!=null){
          array2D = new String[list.size()][];
          for(int i=0; i< list.size(); i++){
              array2D[i] = list.get(i).split(delimiters);
          }
      }else{
          return null;
      }
      return array2D;
  }

  public static ArrayList<String> fileToList(
              File inputFile,
              String encoding
  ){
      ArrayList<String> list = null;
      try {
          //ファイルの読込
          BufferedReader br = new BufferedReader(
                  new InputStreamReader(
                      new FileInputStream(inputFile), encoding
                  )
          );

          list = new ArrayList<String>();
          String strLine;
          while((strLine = br.readLine()) != null) {

              list.add(strLine);
          }
          br.close();
      } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      } catch (IOException e){
          e.printStackTrace();
      } catch (NumberFormatException e){
          e.printStackTrace();
          return null;
      }
      return list;
  }
}
グレーの部分は、今回は使っていません。


コマンドライン
>cd ws
ws>javac -encoding UTF-8 Sample07_01.java
ws>java Sample07_01
floor01.txt
001001 001010 001010 001100 001001 001000 001000 001110 001101 061101
000101 001011 001110 000101 000011 000010 000110 001001 000110 000101
000011 001000 001010 000020 001010 001000 001010 000100 001111 000101
001101 000101 001001 002100 001101 000101 061101 000011 521210 000112
000111 000101 000011 000110 000101 000101 000211 a41102 001111 001101
001001 000010 001100 001001 000100 000201 451112 000201 001012 000100
000101 001101 000101 000011 000110 000101 001011 000010 001100 000101
220201 000102 000101 001011 001010 000110 001011 001110 000101 000101
000101 000111 000011 001010 351110 b31021 001010 001010 000110 000101
000011 001010 001010 151110 071011 c52110 451011 001010 001010 000110
end

floor02.txt
351101 001011 001100 001001 001010 001010 001100 001011 001110 071101
000011 001100 000111 000101 001001 001100 000011 001010 521200 000112
001111 000001 001010 000100 000001 000010 001010 001100 000101 001101
001011 000110 001111 000101 000111 001101 071101 000111 000101 000101
001101 001001 001200 000002 001010 000100 000211 a41102 000101 000101
000201 000012 000110 000111 001111 000011 001010 000110 000101 000111
000011 001100 951121 001101 651121 001001 001000 001010 000010 001100
001101 000011 002020 000000 002020 000000 000100 001011 001110 000101
000011 001100 852111 000101 752111 000001 000010 001010 001010 000100
001111 000011 001010 000010 001010 000110 001011 001010 001110 000111
end



萌えJava超入門 萌えJava超入門 萌えJava超入門
3次元配列ともなると
コマンドラインに
きれいに表示するのって
意外と面倒だな。

何はともあれ、上手く読み込めたようですね。
次のページでは、実際に「GUI版ダンジョン探索プログラム」に適用してみましょう。



お疲れ様でした。




© 2019 awasekagami