2010年2月25日木曜日

Vimの画面分割

Vimの画面分割を使うはめっちゃ便利です。画面分割しても、基本キーボードのみで画面間を移動できるし。
特に大きいサイズのディスプレイ使ってると画面を分割しまくって関連するファイルや、同一ファイルのほかの部分を参照しながら開発できるので、かなり生産性アップの予感です。
単なるたて分割だと、下の画像みたいになるけどアクティブな画面で分割を行うとさらに分割されるよ。

●分割するとこんな感じ

















●画面分割のコマンド
操作内容コマンド
縦分割Ctrl-w + v
横分割Ctrl-w + v
分割サイズを均等にCtrl-w + =
右の画面へ移動Ctrl-w + l
下の画面へ移動Ctrl-w + j
左の画面へ移動Ctrl-w + h
上の画面へ移動Ctrl-w + k
アクティブな画面を閉じる Ctrl-w + c
ほかの画面を閉じる Ctrl-w + o

2010年2月20日土曜日

パック数値とは?


最近パック数値なるものを扱う機会があったので、忘れないようにメモ。

パック数値とは?

  • 1バイトの数字を4ビットで表現する数値のこと。ゾーン数値と比べて単純計算ではあるが、使用容量が半分ですむ。
  • パック数値には、符号なしパックと符号ありパックが存在する。
  • 符号のあらわし方は、末尾の4ビットで表現する。符号なしの場合でも、末尾4ビットで符号なしであることを設定する必要あり。
  • 末尾4ビットが必ず符号領域となるため、ゾーン数値で表した場合の桁数は奇数となる。

【ゾーン数値とパック数値の比較】

10進数数値 ゾーン数値(JISの場合) 符号なしパック 符号ありパック
12345 0x3132333435
(5バイト)
0x12345F
(3バイト)
0x12345C
(3バイト)
+12345 0x31323334C5
(5バイト)
- 0x12345C
(3バイト)
-12345 0x31323334D5
(5バイト)
- 0x12345D
(3バイト)
上記表でも分かるとおり、符合なしは0xFで表現され、プラスは0xC、マイナスは0xDで表現される。

パック数値をアンパックするソース

Javaの場合

// 呼び出し例
// unpack(new byte[]{0x01, 0x2F});  -> 12
// unpack(new byte[]{0x00, 0x00, 0x33, 0x44, 0x0D}); -> -33440
public static long unpack(byte[] pack) {
    long num = 0;
    int weight = 1;
    for (int i = pack.length - 1; i >= 0; i--) {
        num += (pack[i] >> 4) * weight;
        weight *= 10;
        if (i != 0) {
            num += (pack[i - 1] & 0x0F) * weight;
            weight *= 10;
        }
    }
    byte sign= (byte) (pack[pack.length - 1] & 0x0F);
    if (sign == 0x0F || sign == 0x0C) {
        // nop
    } else if (sign == 0x0D) {
        num *= -1;
    } else {
        throw new IllegalArgumentException("invalid sign");
    }
    return num;
}

ruby

def self.un_pack(pack)
  sprintf("%X", pack).gsub(/^(.+)(.)$/) {|str|
    case $2
      when "F", "C"
        ""
      when "D"
        "-"
      else
        raise RuntimeError.new("illegal sign. sign = [#{$2}]")
    end + $1
  }.to_i
end

2010年2月7日日曜日

ruby1.9で文字コード変換

Unicodeに対応したruby1.9で文字コードを変換してみる。
encodeメソッドを使うことによって文字コードを変換できるらしい。
encode(to_encoding, from_encoding)ってな感じで使う。

サンプルコード

#coding:utf-8
# UTF-8
utf8_str = "あいうえお"
puts utf8_str.encoding # => UTF-8

# UTF-8→SJIS
sjis_str = utf8_str.encode("sjis", "utf-8")
puts sjis_str.encoding # => SJIS

実行結果

UTF-8
Shift_JIS

ファイル入出力時のエンコーディングはどう指定するんだろう。Javaだと明示的にしていしないと、
OSのデフォルトエンコーディングで入出力されるんだが。こんど調べてみるか。

【Oracle】JDBC経由でBLOBデータ取得

JDBC経由でBLOBデータを更新する場合は、JCBC経由でBLOBデータ挿入を参照。

JDBC経由でBLOBデータを参照するにはいくつかの方法があると思うので、パターンごとに実装方法をまとめてみた。

取得されるサイズが少量の場合

データベース上のBLOBのサイズが小さい場合は、ResultSet#getBytesを使って一括でメモリ上に展開するのが良いと思う。
実際にのコードは、こんな感じになる。
PreparedStatement statement = con.prepareStatement( 
        "select blob_data FROM blob_test where id = ?"); 
try { 
    statement.setString(1, "01"); 
    ResultSet set = statement.executeQuery(); 
    if (set.next()) { 
        // ResultSet#getBytesを呼び出して、BLOBのデータを取得する。 
        byte[] bytes = set.getBytes(1); 
    } 
} finally { 
    statement.close(); 
}


取得されるサイズが大きい場合

取得されるBLOBのサイズが大きくなる場合(例えばファイルをBLOBのカラムに格納していた場合)は、メモリ上にすべてのデータを展開するとヒープを圧迫するのでよろしくない。
このような場合は、一定サイズを読み込みつつファイルなどに落としてあげるのが良い。
コードは、こんな感じ。Blobから取得したInputStreamからデータを読み込んでファイルなどに出力してあげれば良い。
PreparedStatement statement = con.prepareStatement( 
        "select blob_data FROM blob_test where id = ?"); 
try { 
    statement.setString(1, "01"); 
    ResultSet set = statement.executeQuery(); 
    if (set.next()) { 
        // getBlobを呼び出し、Blobオブジェクトを取得する。 
        Blob blob = set.getBlob(1); 

        // BlobオブジェクトからInputStreamを取得 
        InputStream stream = blob.getBinaryStream(); 
        printFile(stream); 
    } 
} finally { 
    statement.close(); 
}