ファイルをinputstreamに読み込んで、バイト配列をDBに保存する。

2008-01-23 - suusuke@Hatenaコレを書いたとき、実はファイルをDBに保存したかった。


でも、java.io.Fileを直列化(シリアライズ)して、DBに格納しても復元するとき、Fileオブジェクトを直列化したものを復元するから、結局元ファイル(直列化する前にFileオブジェクトが参照していたファイル)がないとだめ。これじゃ、直列化して、DBに入れる意味がない…。


RwJ:[Java]画像ファイルを自由に圧縮出来るTips


上記サイトをたまたまみて、解決しました。
何も、Fileオブジェクトを作る必要が無かった。ImputStreamをそのまま、ByteArrayOutputSteamでByteArrayOutputSteam自身(メモリ上に)に書き込めば良いんだ。


ついでなので!?、s2jdbcを使って書いてみた。
まずは読み込み。

package jp.co.suusuke;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import jp.co.suusuke.entity.Image;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

public class S2jdbcBlobWriteSample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SingletonS2ContainerFactory.init();
		S2Container container = SingletonS2ContainerFactory.getContainer();

		JdbcManager jdbcManager =
			(JdbcManager) container.getComponent(JdbcManager.class);

		try {

			File file =
				new File(
					"C:/image.jpg");

			InputStream inputStream = new FileInputStream(file);

			Image image = new Image();
			image.setUid(1);
			image.setIid(1);
			image.setImage(getBytes(inputStream));

			int count = jdbcManager.insert(image).execute();

			System.out.println(count);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * InputStreamをバイト配列に変換する
	 * 
	 * @param is
	 * @return バイト配列
	 */
	private static byte[] getBytes(InputStream is) {
		// byte型の配列を出力先とするクラス。
		// 通常、バイト出力ストリームはファイルやソケットを出力先とするが、
		// ByteArrayOutputStreamクラスはbyte[]変数、つまりメモリを出力先とする。 
		ByteArrayOutputStream b = new ByteArrayOutputStream();
		OutputStream os = new BufferedOutputStream(b);
		int c;
		try {
			while ((c = is.read()) != -1) {
				os.write(c);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		// 書き込み先はByteArrayOutputStreamクラス内部となる。
		// この書き込まれたバイトデータをbyte型配列として取り出す場合には、
		// toByteArray()メソッドを呼び出す。 
		return b.toByteArray();
	}

}

次に復元。

package jp.co.suusuke;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import jp.co.suusuke.entity.Image;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

public class S2jdbcBlobReadSample {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		SingletonS2ContainerFactory.init();
		S2Container container = SingletonS2ContainerFactory.getContainer();

		JdbcManager jdbcManager =
			(JdbcManager) container.getComponent(JdbcManager.class);

		try {

			List<Image> images = jdbcManager.from(Image.class).getResultList();

			for (Image image : images) {
				System.out.println(image);
				write(image.getImage());
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static void write(byte[] byteData) {

		File outputImageFile =
			new File("C:/a.jpg");
		InputStream inputStream = new ByteArrayInputStream(byteData);

		OutputStream os = null;
		try {
			os =
				new BufferedOutputStream(new FileOutputStream(outputImageFile));
			int c;
			while ((c = inputStream.read()) != -1)
				os.write(c);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (os != null) {
				try {
					os.flush();
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

image entity

package jp.co.suusuke.entity;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Image implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5149047466767013156L;

	@Id
	private Integer uid;

	@Id
	private Integer iid;

	private byte[] image;

	public Integer getUid() {
		return uid;
	}

	public void setUid(Integer uid) {
		this.uid = uid;
	}

	public Integer getIid() {
		return iid;
	}

	public void setIid(Integer iid) {
		this.iid = iid;
	}

	public byte[] getImage() {
		return image;
	}

	public void setImage(byte[] image) {
		this.image = image;
	}

}