プロジェクトは Bitbucket で公開してみました。
内容は Windows のサンプル画像を 200KB 毎に分割し、それを結合する。というものです。
src.jpg
ファイル操作には Apache Commons の Commons IO を使っています。ダウンロードは こちら から。
あと、SD カード上でファイル操作を行うのでマニフェストにパーミッション追加をお忘れなく。
あと、SD カード上でファイル操作を行うのでマニフェストにパーミッション追加をお忘れなく。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
MainActivity.java
package com.gmail.hyukix.sample_131210_01;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Collection;
import java.util.Locale;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 分割するファイル
File src = new File(Environment.getExternalStorageDirectory(),
"Sample/src.jpg");
if (!src.exists()) {
String msg = "分割対象ファイルがありません。\n" + src.getAbsolutePath();
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
return;
}
// 断片ファイルの拡張子
String ext = "tmp";
// 結合先のファイル
File dst = new File(Environment.getExternalStorageDirectory(),
"Sample/dst.jpg");
// ファイル分割 (src.jpg を 200KB 毎に *.tmp へ分割)
String msg = split(src, ext, 200 * 1024) ? "分割成功!!" : "分割失敗...";
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
// ファイル結合 (*.tmp を dst.jpg へ結合)
msg = combine(dst, ext) ? "結合成功!!" : "結合失敗...";
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
/**
* ファイル分割
*
* @param src 分割ファイル
* @param ext 断片ファイルの拡張子
* @param size 断片ファイルの最大ファイルサイズ
*/
private boolean split(File src, String ext, int size) {
try {
// 分割ファイルのストリーム
FileInputStream in = new FileInputStream(src);
int cnt = 0;
while (0 < in.available()) {
// 断片ファイルを作成
String dirPath = src.getParent();
String fileName = String.format(Locale.JAPAN, "%08d.%s", ++cnt, ext);
File dst = new File(dirPath, fileName);
FileUtils.touch(dst);
// 断片ファイルへデータ書き出し
FileOutputStream out = new FileOutputStream(dst);
IOUtils.copyLarge(in, out, 0, size);
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
/**
* ファイル結合
*
* @param dst 結合ファイル
* @param ext 断片ファイルの拡張子
*/
private boolean combine(File dst, String ext) {
try {
// 断片ファイルをリスティング
File dir = dst.getParentFile();
String[] extensions = { ext };
boolean recursive = false; // サブディレクトリは対象外
Collection<File> files = FileUtils.listFiles(dir, extensions, recursive);
// 断片ファイルを走査
for (File file : files) {
// 断片ファイルのデータ
byte[] data = FileUtils.readFileToByteArray(file);
// 結合ファイルのストリーム
boolean append = true; // 追記する
FileOutputStream out = FileUtils.openOutputStream(dst, append);
// 断片ファイルを順次結合
IOUtils.write(data, out);
}
return true;
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
}
/mnt/sdcard/Sample/src.jpg が存在しない場合は左図が表示されます。
存在する場合は分割、結合を行い、右図が表示されます。
存在する場合は分割、結合を行い、右図が表示されます。
エミュレータで実行した様子が下図です。
結合した dst.jpg が元の src.jpg と同じ内容になっていることを確認できました。
こういうのの定石はあるのかしらん。



