はじめに
こんにちは、まっきーです。今回は書いていたと思って書いていなかった固定長のデータを、Digit数で読み込む方法を解説したいと思います。
前回は固定長ではなくて文字数で区切る方法を解説しました。そして前回、全角と半角が混じっている場合はうまく区切れないですね!ということだけ投げてじゃあその場合どうすんの?というところをカバーしていませんでした。
今回はきちんと半角と全角が混じっているファイルでも区切れる方法を解説します。
※この方法Macでは動きませんでした。デフォルトの文字コードの違いからかもしれません。原因分かればまた記事書こうと思います。
今回のテーマ ~Java Snippet~
Java Snippet Nodeを使って固定長のデータを複数コラムに分割していきます。
JavaのNodeを初めてみる方は、まずは下記の記事を読んでみてください。
固定長のファイルとは?
そもそも固定長ファイルという言葉をご存知でしょうか。コトバンクによると、固定長は下記の定義になっています。
長さ・桁数・文字数・データの大きさなどが定められていること。特に、コンピューターで、レコード(ファイルを構成する単位)の長さが一定である形式を指す。⇔可変長。
引用:
固定長というのは、長さが決まっているということです。あらかじめ決めた区切り位置のルールに沿って、それぞれ値を入れていくイメージです。
テキストファイルには、いくつかの区切り方があったと思います。カンマ区切り、タブ区切り、スペース区切り等です。この固定長ファイルは、この区切りが長さで決められているものです。
今回は下のような固定長ファイルを用意してみました。上の方に半角スペースを1digitとしたメモリが振られているので、すこし分かるかもしれませんが、あらかじめ決めておいたDigit数から各値がスタートするイメージです。
固定長ファイルはかなり一般的なので、Nodeとして用意されていてもおかしくないのですが、どうやらまだないみたいです。
fixed length input - KNIME Analytics Platform - KNIME Community Forum
古い基幹システムからバッチ処理で吐き出されるファイルの多くはこの固定長ファイルとなっているので、かなりビジネスケースとしては大きいと思うのですが、、、
ぜひ作っていただきたいですね。
覚えてほしいこと
- new String(sbyte, 開始digit数, Digit長さ);
- 半角は1digit, 全角は2digit
日本語は全角なので、英語の2倍スペースを取ってます。
やりたいこと
下のような固定長のデータを読み込んでいきます。今回はスペースが半角となっているため、文字数で区切る方法(Cell splitterやFixed width file reader)は使用できません。
固定長ファイルの読み込み方
Workflow
Workflowは下のようになります。
まず、File Readerでファイルを1つのコラム、複数の行として読み込みます。
次に今回解説するJava Snippetで、Digit数でコラムを区切っていきます。
最後に、元々のコラムを削除して、Headerを挿入したら完成です。
Workflowは下記からダウンロードできます。
固定長ファイルを読み込む fixed length input ~Java Snippet~ – KNIME Hub
Step1 - File ReaderのConfigure - 1つのコラムとして取り込む
まずは、File Readerについてです。Column delimiterをnoneにすることにより、1つのコラムとして取り込むことができます。
MACの場合は、DefaultのCharacter decodingが、”UTF-8”だと思うので、user definedから、正しく読めるようにShift-JISを指定しました。
Step2 - Java Snippet Nodeで、Digit数によってコラムを分割する
ここが今回のメインの部分、Java Snippet NodeでDigit数を元にコラムを分割する部分です。文字列を一度、バイト配列に変換して、もう一度文字列に戻すという作業を行っています。
Charsetクラスの追加 - system imports
まず、String型をByte型という方に変換する際に使うクラスをImportします。文字コードを指定する際に使用します。
System importsの下にコピペしてみてください。このクラス、使わなくても変換出来きるのですが、一応Importの練習のために入れておきます。
String型からByte型の変換 - expression
まずは、String 型をByte型に変換します。これは呪文だと思ってください。
これで、文字列をShift_JISの文字コードに変換した結果を、「sbyte」という変数に格納していきます。この、「c_Col0」の部分は、File Readerで取り込んだコラムになります。また、"Shift_JIS"の部分でEncodingを指定しています。「Charset.forName("Shift_JIS")」の部分はなくても動いたりします。OSが変わらない前提です。
Byte型からString型の変換 - expression
次にByte型からString型に変換していきます。下のようにOutputコラムを作った後に、開始位置と長さを書いていきます。
Output Column = new String(sbyte, 開始digit数, Digit長さ);
Outputコラムの名前はひとまず、Col1、Col2というようにしてみました。
Confirm - before after
実行すると、このように元コラムを元に複数コラムに分割できていることが分かります。
Step3 - 不要コラムを削除
ここまでくれば、もうほとんど終わったようなものです。まずは最初に取り込んだコラムが不要になったので削除します。
Step4 - コラム Headerを挿入する
さて、最後にHeaderを挿入していきます。方法は下記の記事で解説した通りです。
Header行とデータ行の分割
まずは、全体のテーブルから1行目だけを分割して、コラムヘッダーの行と、データの行を分割していきます。
コラムヘッダの挿入
Transposeで、Headerの行を横から縦に変換していきます。すると、Insert Column HeaderでLook upする形にすることができます。
最終Output
これできれいに固定長を KNIMEに取り込むことができました!
ちょっと一言
Javaで文字列・バイト配列変換を行うときに使用するクラスについて
下記の記事によると、Shift-JISはStandardCharsetsクラスで用意されていないようなので、Charset.forNameを使用しています。
Charset.forNameでUnsupportedEncodingExceptionを回避する - Qiita
また、GetBytesにCharsetを渡せるのはJava6以降のようです。
Macでは文字化けしてしまったので、文字コード変換についての記事をいくつか探しましたが、よくわかりませんでした、、、
もしMacでできた方いたら教えていただきたいです。
Digit数を数えるためのおすすめテキストエディタ紹介
Digit数を数えていくの大変ですよね。テキストエディタを使えばDigit数を数える補助をしてくれます。簡単なテキストエディタで全然構わないです。
私が今回使っていたテキストエディタはTerapadというものです。下にメモリがついている簡単なテキストエディタをいくつか紹介しておきます。
Digit数を数えるためだけなので、メモリがついていてなおかつ動作の軽いソフトという基準で選んでいます。
無料、メモリあり、動作も軽いです。
無料、メモリあり、動作も軽いです。
メモリあり、動作も軽いです。有料ですが、無料化の方法が公開されています笑
研究室時代お世話になってました。本来有料エディタなので、機能が豊富です。
Ctrl + Shift + マウスの右ボタンを押しながらしながら「はい」をクリック
秀丸エディタのダイアログを表示させなくする方法 | 覚え書き.com
おわりに
きちんと動いたでしょうか。正直、この方法はしょうがなく使っている節があるので、もっといいやり方があれば知りたいです。また、この方法、デフォルトの文字コードの設定の問題か、MACでは動きませんでした。MACでどうやるのか、気になります。
もしご存知の方いたら教えていただけると大変嬉しいです。
基幹システムのような古くからあるシステムから自動的に吐き出されるファイルの多くが固定長ファイルだと思います。KNIMEの方々、ぜひ、OSに依存しないようなNode作っていただきたいです!(願望)
海外は全角があまりないので、問題にならないのかもしれませんね、、、ファイルが全て半角や全角で統一されていれば、文字数で区切れるFixed width file readerなどがあるので問題なく取り込まれると思います。
上級編ということで少し省略気味に書いていってます。ここ分からないというところがあれば指摘いいただけれ場と思います。ではまた!
余談
ブラックフライデーですね! 皆さん買い物捗っていますか?私はまだ買うものが思いつかず苦労しています。ちょっとよく分からないですが、自分の買うものリスト、買ったものリスト、共有しておきますね。
¥20,000 (税込) 以上買い物すれば、ポイントバックがあるみたいです。これを機に大きな買い物もありです、、、
生活必需品系
ひとまず生活必需品は買い溜めできますね!
マスク
この前洗えるマスクを購入したのですが、かなり良かったので共有します!触り心地が最高でした。
毎日使い捨てマスクはちょっと経済的にも痛かったので非常に満足でした。
【Amazon限定ブランド】マスク ひんやり 4枚組 男女兼用 フィット感 耳が痛くなりにくい 呼吸しやすい 伸縮性抜群 立体構造 丸洗い 繰り返し使える レギュラー グレー Home Cocci
- メディア: ホーム&キッチン
食器用洗剤
つい昨日切れたのでちょうどよかったです。10回分もあれば当分困りません。
シャンプー
シャンプーもこんだけあったら余裕で持ちます。
ボディーソープ
ボディーソープもこんだけあったら当分買わなくていいです笑
【Amazon.co.jp限定】 Dove(ダヴ) 【大容量】ボディソープ(ボディウォッシュ) プレミアム モイスチャーケア 詰替え用 超特大 2800g
- 発売日: 2020/04/04
- メディア: ヘルスケア&ケア用品
洗濯洗剤
ジェルボール楽ですよね!
在宅勤務用品
在宅勤務の環境整えると、仕事めっちゃ捗ります。
ディスプレイ
ディスプレイは必須ですよね。2画面使うと作業効率が全然違います。
【Amazon.co.jp 限定】I-O DATA モニター 23.8型 スピーカー付 ADSパネル 非光沢 HDMI×1 3年保証 土日サポート EX-LDH241DB
- 発売日: 2019/10/01
- メディア: Personal Computers
ディスプレイアーム
ディスプレイを上下で2画面使うとほんと便利です。
キーボード
ワイアレスキーボードもいいですよね。大きなモニタがメインになるので作業しやすくなります。
参考リンク
- KNIME公式Node Pit(英語):
Fixed Width File Reader — NodePit
- KNIME Example Workflow(英語):
Fixed Width File Reader – KNIME Hub
- KNIME Community(英語):
fixed length input - KNIME Analytics Platform - KNIME Community Forum
- Javaクラス java.nio.charset.Charset について:
- その他Javaの文字コード変換について