Javaのファイル読み込み、書き込みを整理 その1

Javaのファイル読み込み、書き込みに関する知識がごちゃごちゃしているので整理してみました。
誤解している箇所もあると思いますので、指摘してもらえると助かります。

目的

  • Javaのファイル読み込み、書き込みの機能を体系付けて分類する。
  • 使い方を整理する。

分類

Javaのファイル読み込み、書き込み機能は大雑把に4種類に分類されます。
分類の要素は

  • 対象(多くはファイル)がテキスト形式かバイナリ形式か
  • 対象への操作(読み、書き)

の2つで、下記のようになります。

テキスト バイナリ
Reader InputStream
Writer OutputStream

今回はこれらのうち、テキスト形式を取り扱う「Reader」を整理してみます。

Readerの階層構造

テキストを読み込む機能は、Readerクラスを頂点として下記のような階層構造になっています。

色々ありますが、

の2つの利用頻度が多いと思われます。

FileReaderとInputStreamReader

FileReaderと同じファイル読み込み機能を持つものにInputStreamReaderがあります。

これらの2つの違いは、

  • InputStreamReaderは文字コードを指定できるが、FileReaderは実行環境のデフォルト文字コードを利用する。
  • InputStreamReaderはバイナリとテキストの橋渡しをするのが本来の役割。なので、ファイルの読み込み以外にも利用できる。

です。

使い方(テキストファイルの読み込み)

InputStreamReader, FileReaderそれぞれを利用してテキストファイルを利用する場合は、以下の手順が必要になります。

InputStreamReaderはバイナリの橋渡しする分一手間かかります。
また、いずれの場合も効率良くファイルを読み込むためにBufferedReaderに集約します。

コードにすると、
InputStreamReaderの場合

FileInputStream fs = new FileInpustStream("hoge.txt");
InputStreamReader isr = new InputStreamReader(fs, "UTF8");
BufferedReader br = new BufferedReader(isr);

FileReaderの場合

FileReader fr = new FileReader("hoge.txt");
BufferedReader br = new BufferedReader(fr);

となります。
文字コードを意識する必要がない場合はFileReaderを利用するのが楽ですね。

BufferedReaderを作成した後はテキストを読み取ります。

FileReader fr = new FileReader("hoge.txt");
BufferedReader br = new BufferedReader(fr);

//char配列として読み取る。
char[] buffer = new char[1024];
br.read(buffer, 0, 1024);

//Stringとして一行ずつ読み取る。
StringBuffer text = new StringBuffer(1024);
String line;
String lineSeparator = System.getProperty("line.separator");
while( (line = br.readLine()) != null) {
    text.append(line);
    text.append(lineSeparator);
}

Readerに関してはこんなところでしょうか。

参考

Java〓 Platform, Standard Edition 7 API Specification
http://docs.oracle.com/javase/7/docs/api/index.html

WebViewに拡大縮小機能とつける

WebViewに拡大縮小機能をつける方法です。

やり方

WebViewの変数を

private WebView mWebView;

とした場合、以下のような手順で実現できます。

1.拡大縮小機能をオンにする

WebSettingsクラス のsetSupportZoom メソッドにtrueを渡してあげると、拡大縮小機能をWebViewに付加されます。

mWebView.getSettings().setSupportZoom(true);
2.拡大縮小ボタンをつける

WebSettingsクラス のsetBuiltInZoomControls メソッドにtrueを渡してあげると、WebViewに拡大縮小ボタンが表示されます。

mWebView.getSettings().setBuiltInZoomControls(true);

補足

ちなみに、ページを全体表示にする設定の状態で1番をすると、ピンチイン・ピンチアウトで拡大縮小ができるようになります。なので、2番についてはオプション的な扱いかもしれません。

WebViewでロードしたページ全体を表示する

WebViewを弄ってみて、ページ全体を表示するのに偉い苦労したので忘れず記録しておきます。

やり方

WebSettingsを使って、WebViewのWide ViewPortとOverviewモードをONにする。

コード

@Override
public void onCreate(Bundle savedInstanceState){
    //(中略)
    WebView mWebView = (WebView) findViewById(R.id.hoge);
    mWebView.getSettings().setUseWideViewPort(true);
    mWebView.getSettings().setLoadWithOverviewMode(true);
    mWebView.loadUrl("hogehoge");
}

解説

WebSettingsの

  • setUseWideViewPort(true)でWide ViewPortをON
  • setLoadWithOverviewMode(true)でOverviewモードをON

にしています。

Wide ViewPortでは、ページのサイズが画面サイズよりも大きい場合に画面に収めるように縮小できます。また、Overviewモードはページが画面に収まるように自動で縮小します。
Wide ViewPortとOverviewモードを組み合わせることで、ロードしたページ全体が画面に表示されるようになります。
※挙動から推測なので違うかもしれません。

maven用社内リポジトリを構築する

自作やベンダー提供のライブラリをプロジェクトで利用する場合、社内リポジトリを利用するのが一般的のようです。
そこで今回は社内リポジトリを構築して見たので、忘れないようにまとめてみます。

参考にしたサイトは以下の通りです。感謝。

nulab 構成管理実践入門
http://www.nulab.co.jp/kousei/chapter1/01.html
Ussy Diary インハウスリポジトリサードパーティのライブラリをデプロイする
http://www.pshared.net/diary/20090212.html
はじめての自宅サーバ構築
http://kajuhome.com/

webdav構築

まず、社内リポジトリの公開用環境としてWebDAVを構築します。
構築方法は、ここを参考にしました。
ただ、WebDAVの設定ファイルがそのままでは使えませんでした。
私の環境だけかもしれませんが一応設定を書いておきます。

# vi /etc/httpd/conf.d/webdav.conf
#
# This is to permit URL access to WebDav.
#
Alias /webdav/ "/var/www/html/webdav/"
<IfModule mod_dav.c>
    DAVMinTimeout 600
    <Location /webdav>
        DAV On
        AuthType        Basic
        AuthName        "Login WebDAV"
        AuthUserFile    "/etc/httpd/conf/.htpasswd"
        Require "$WebDAVログイン用ユーザID"
        Order deny,allow
        Deny from all
        Allow from all
    </Location>
</IfModule>

これで/var/www/html/webdav/に社内リポジトリとして利用できる環境ができました。
また、アクセスする際にはBASIC認証がかかります。

pom.xmlの編集

次にここを参考にpom.xmlを編集して、社内リポジトリを利用できるようにします。
私の場合、以下の項目を参照しました。

mvnコマンドでjarファイルを設置

これでライブラリを社内リポジトリに設置できるようになりました。
設置方法はここの「リモートリポジトリにサードライブラリのソースをデプロイ」を参照しました。
このサイトだとscpを使って設置していますが、私の環境だとWebDAVなので

-Durl=scp://192.168.10.10/home/maven2

という記述が

-Durl=http://192.168.10.10/home/maven2

となります。


これで、社内リポジトリにライブラリを追加できました。
あとは実際にプロジェクトの依存関係に追加してあげられば利用できるようになります。

mavenで文字化けを解消するための備忘録

ようやくmavenを本格的に利用することになり、環境構築を進めています。
その中で、文字化けの問題に躓いたので忘れないようにメモを取っておきます。

事象

maven compile実行中に日本語が文字化けする。

環境

lion
Apache Maven 3.0.3

原因

terminalの文字コードUTF-8MavenJava文字コードSJISだったから。

対処法

mavenJava文字コードUTF-8する。

maven文字コード設定

pom.xmlmaven-compiler-pluginを追加する。

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <encoding>UTF-8</encoding>
    <source>1.6</source>
    <target>1.6</target>
  </configuration>
</plugin>

Java文字コード設定

.bashrcか.bash_profileに以下を追加する。

export _JAVA_OPTIONS="-Dfile.encoding=UTF-8"


ほんとうはjenkinsの環境を構築したいですが、なかなかたどり着けません。

CentOSでCmakeを動かすための備忘録

CentOS6.0で開発環境を構築する際にちょっとハマった部分があったので、同じ轍を踏まないための備忘録です。

MySQL 5.5.16をソースコードからインストールする際にCmakeを使うためにインストールしたソフト一覧です。

※全てyumでOK。

Cmakeもyumでインストールしたのですが、上記のソフトは依存関係にはふくまれていないようですね。

S2JDBCでのjoinについての備忘録

業務でS2JDBCを使っているのですが、テーブル結合のやり方がわかったので簡単に備忘録を残します。

ポイントは、

  1. テーブル間の結合定義
    1. プロパティの追加
    2. アノテーションの設定
    3. 結合カラムの設定
  2. joinの記述

です。

例題

以下のような二つのテーブルをinner joinしてみよう。

TABLE_ONE

名前 P
id int
name varchar(20)
info_id int
crete_time datetime

TABLE_TWO

名前 P
id int
keyword varchar(20)
crete_time datetime

なお、二つのテーブルの関係性はテーブル1:テーブル2 = n:1(多対1)。
外部キーは使わない物とする。
TABLE_ONEのエンティティ名をTableOne、TABLE_TWOのエンティティ名をTableTwoとする。

テーブル間の結合定義

プロパティの追加

まずテーブル同士の結合を定義する(?)ために、各エンティティにプロパティを追加します。

public class TableOne {
  //テーブルのカラムに対応したプロパティ
  public int  id;
  public String name;
  public int info_id;
  public TimeStamp create_time
  //テーブル間の結合を定義
  public TableTwo tableTwo; //<--結合先のエンティティを追加
}

public class TableTwo {
  //テーブルのカラムに対応したプロパティ
  public int id;
  public String keyword;
  public TimeStamp create_time;
  //テーブル間の結合を定義
  public List<TableOne> tableOneList; //<--結合先のエンティティを追加
}

テーブルが多対1で結合する場合、

  • 多のエンティティに1のエンティティを、 ----A
  • 1のエンティティに多のエンティティを、 ----B

プロパティとして定義します。
ここで注意が必要なのは、Bの場合はプロパティをListとして追加することです。

アノテーションの設定

続いて、追加したプロパティに多対1の関連性を定義するため、アノテーションを設定します。

public class TableOne {
  //テーブルのカラムに対応したプロパティ
  public int  id;
  public String name;
  public int info_id;
  public TimeStamp create_time
  //テーブル間の結合を定義
  @ManyToOne                //<--TableOneが多対1の多であることを追加
  public TableTwo tableTwo;
}

public class TableTwo {
  //テーブルのカラムに対応したプロパティ
  public int id;
  public String keyword;
  public TimeStamp create_time;
  //テーブル間の結合を定義
  @OneToMany(mappedBy="tableTwo")   //<--TableTwoが多対1の1であること、自身がTableOneで
                   //   tableTwoとして定義されていることを追加
  public List<TableOne> tableOneList; 
}
結合カラムの設定

さて、結合の定義の詰めとしてどのカラムを結合条件として使うかを設定します。

public class TableOne {
  //テーブルのカラムに対応したプロパティ
  public int  id;
  public String name;
  public int info_id;
  public TimeStamp create_time
  //テーブル間の結合を定義
  @ManyToOne
  @JoinColumn(name="info_id", referencedColumnName="id") //<--結合カラムを指定
  public TableTwo tableTwo; 
}

public class TableTwo {
  //テーブルのカラムに対応したプロパティ
  public int id;
  public String keyword;
  public TimeStamp create_time;
  //テーブル間の結合を定義
  @OneToMany(mappedBy="tableTwo")
  public List<TableOne> tableOneList; //<--結合先のエンティティを追加
}

@ManyToOneが設定されている方に、@JoinColumnを追記することで実現します。
()のnameでTableOne、referencedColumnNameでTableTwoの結合カラムを指定しています。
特に何も指定しない場合は、それぞれの主キーが結合カラムになるようです。


これで、結合定義は完了です。

joinの記述

こんな風に記述できます。

List<TableOne> tableOneList = jdbcManager.from(TableOne.class).("tableTwo").getResutList();

ここで重要なのが"tableTwo"という記述。
結合対象はテーブル名ではなく、エンティティで定義しているプロパティ名を指定します。

これで、joinはバッチリ!!・・・のはず。

参考サイト

以下のサイトを参考にさせてもらいました。 感謝。

S2JDBC
公式サイト。ここで基本はバッチリ。ただ結合に関する説明はちょっと不足してる感じ。
S2JDBCでJOINのやり方をいつも忘れるからメモ
結合に関する情報を補完してくれた記事。実際にどう書くかが明記されているので助かりました。
S2JDBCで、結合カラムが複数ある場合のアノテーション
結合カラムに関する説明をしてくれた記事。