読者です 読者をやめる 読者になる 読者になる

DojaでSD-Bindingするラッパー

ガラケー

今回、go2east4u6r6というドコモ携帯用のアプリを作っていて、SD-Binding関連のラッパーを作りました。
アプリを公開したばかりなのでバグが含まれてる可能性ありますが、しばらくこれで運用しようかと思います。
ちなみに、String入出力関係はボキが使ってないので未検証です。

対応はDoja5.0以上。
その他、留意点は↓のnoteにチョコチョコ書いてます。

import java.io.*;
import com.nttdocomo.device.*;
import com.nttdocomo.fs.*;
import com.nttdocomo.io.*;

/**
 * SDカード関連のラッパー
 * 
 * @author tonogata
 * @note
 * SD-Bindingの対応はDoja5.0=903i系以降だが、D703iは非対応
 * SDカードのアクセス制御は一番緩くしてます。変更する場合はtoken()内の定数をいじる
 * todoに「書いただけ」とあるのは、ボキが実際に使ったことないメソッド
 * 使えるファイル名は半角英数8文字までで、先頭は英字がベターだったような。
 * PCからSDにファイルを作りたい場合、新規ファイル作成はできないので、
 * あらかじめ携帯側でファイルを作り、PCからはそこに書き込む
 * ちなみにフォルダは作れない
 * このファイルをsrc内に設置して、importする。使い方は↓(要try-catch)
 * @code
 * try{
 *     String status = Sd.obj().checkDevice();
 *     if(status != null) System.err.println(e.toString());      // デバイスチェック
 *     Sd.obj().fileWriteStr("sample.txt","ほんぶんだぴょーん"); // ファイル作成
 *     String text = Sd.obj().fileReadStr("sample.txt");         // ファイル読取
 *     System.err.println(text);
 * } catch (Exception e) {
 *     System.err.println(e.toString());
 * }
 * 
 */
final public class Sd {
 
 /** デバイス名(これしか規定されていないので固定) */
 final private static String DEVICE_EXT = "/ext0";
 
 /** アクセス権限 */
 private static DoJaAccessToken _token = null;
 
 /** デバイス */
 private static StorageDevice _device = null;
 
 /** フォルダー */
 private static Folder _folder = null;
 
 /** このクラスのインスタンス */
 private static Sd _obj = null;
 
 /**
  * 不可視のコンストラクタ(シングルトン)
  */
 private Sd(){}
 
 /**
  * インスタンス生成
  * @return object このクラスのインスタンス
  */
 public static Sd obj(){
  if(_obj == null) _obj = new Sd();
  return _obj;
 }
 
 /**
  * SDが使えるかチェック
  * @return string ok=null / error=エラーメッセージ
  */
 public String checkDevice(){
  try{
   device().getFolder(token());
   return null;
  } catch (Exception e){
   return "SDカードが読み取れません:" + e.toString();
  }
 }
 
 /**
  * ファイルリストの取得
  * @return com.nttdocomo.fs.File[] ファイルリスト 
  * @throws Exception
  * @todo 書いただけ
  * @note
  * 取り出したファイルリストの属性取得は
  * for($i=0;i<fs.length;i++){
  *   System.err.println(fs[i].getPath());   // ファイル名(絶対パス) 先頭に「/」が付いてます
  *   System.err.println(fs[i].getLength());   // ファイルサイズ
  *   System.err.println(fs[i].getLastModified()); // ファイルの更新日時
  * }
  */
 private File[] getFileList() throws Exception {
  try{
   File[] fs = this.folder().getFiles();
   if(fs == null || fs.length == 0) return null;
   return fs;
  } catch (Exception e) {
   throw new Exception("getFileList()=>" + e.toString());
  }
 }
 
 /**
  * ファイル読み込み(byte[])
  * @param path string ファイル名
  * @return byte[] データ
  * @throws Exception
  */
 public byte[] fileRead(String path) throws Exception {
  byte[] result = null;
  FileEntity fe = null;
  try{
   fe = (this.folder().getFile(path)).open(File.MODE_READ_ONLY); //読み込みモードで開く
   FileDataInput fdo = null;
   try{
    //読み込み処理
    fdo = fe.openDataInput();
    long size = fdo.getSize();
    result = new byte[(int)size];
    //result = fdo.readString();
    //result = fdo.readUTF();
    fdo.readFully(result);
   } catch (Exception e){
    throw new Exception("[" + path + "]読込失敗: " + e.toString());
   } finally{
    try{
     fdo.close();
    } catch(Exception e){
     //開けなかった場合
    }
   }
  } catch (Exception e){
   throw new Exception("[" + path + "]読込失敗 :" + e.toString());
  } finally{
   try{
    fe.close();
   } catch (Exception e){
    //開けなかった場合
   }
  }
  
  return result;
 }
 
 /**
  * *ファイル読み込み(String)
  * @param path String ファイル名
  * @return string テキスト
  * @throws Exception
  * @todo 書いただけ
  */
 public String fileReadStr(String path) throws Exception {
  String result = null;
  try{
   byte[] dat = Sd.obj().fileRead(path);
   
   if (dat == null) {
    result = "";
   } else {
    ByteArrayOutputStream temp = new ByteArrayOutputStream();
    temp.write(dat, 0, dat.length);
    result = temp.toString();
    if(temp != null){
     temp.close();
     temp = null;
    }
    if(result == null) result = "";
   }
  } catch (Exception e) {
   throw new Exception(e.toString());
  }
  
  return result;
 }
 
 /**
  * ファイル書き込み及び更新(byte[])
  * @param path string ファイル名
  * @param data byte[] データ
  * @throws Exception
  */
 public void fileWrite(String path,byte[] data) throws Exception {
  try{
   if(this.fileCheck(path)){
    this.fileUpdate(path, data);
   } else {
    this.fileCreate(path, data);
   }
  } catch (Exception e){
   throw new Exception("fileWrite=>" + e.toString());
  }
 }
 
 /**
  * ファイル書き込み及び更新(String)
  * @param path String ファイル名
  * @param data String データ
  * @throws Exception
  * @todo 書いただけ
  */
 public void fileWriteStr(String path,String data) throws Exception {
  if (data == null) data = "";
  try{
   Sd.obj().fileWrite(path,data.getBytes());
  } catch (Exception e) {
   throw new Exception(e.toString());
  }
 }
 
 /**
  * ファイル削除
  * @param path string ファイル名
  * @throws Exception
  */
 public void fileDelete(String path) throws Exception {
  try{
   File file = this.folder().getFile(path);
   file.delete();
  } catch (Exception e){
   throw new Exception("fileDelete=>" + e.toString());
  }
 }
 
 /**
  * 全ファイル削除
  * @throws Exception
  */
 public void fileDeleteAll() throws Exception {
  try{
   File[] fs = this.folder().getFiles();
   if(fs == null || fs.length == 0){
    // ファイル数が0?
    return;
   }
   
   for(int i=0;i<fs.length;i++){
    try {
     String name = fs[i].getPath();
     name = name.substring(1);
     this.fileDelete(name);
    } catch (Exception e) {
     System.err.println(e.toString());
     // とりあえず継続
    }
   }
  } catch (Exception e) {
   throw new Exception("fileDeleteAll=>" + e.toString());
  }
 }
 
 /**
  * Folderを返す
  * @return Folder
  */
 private Folder folder() throws Exception {
  if(_folder == null){
   try{
    _folder = device().getFolder(token());
   } catch (MediaNotFoundException e) {
    throw new Exception("SDカードが挿入されていません\n");
   } catch (Exception e) {
    throw new Exception(e.toString() + "\n");
   }
  }
  return _folder;
 }
 
 /**
  * ファイルの新規作成
  * @param path string ファイル名
  * @param data byte[] データ
  * @throws Exception
  */
 private void fileCreate(String path,byte[] data) throws Exception { 
  try{
   File file = this.folder().createFile(path);
   this.write(file, data);
  } catch (FileNotAccessibleException e) {
   switch(e.getStatus()){
    case FileNotAccessibleException.ACCESS_DENIED:
     throw new Exception("アクセスが拒否されました");
    case FileNotAccessibleException.ALREADY_EXISTS:
     throw new Exception("同名のファイルが存在します");
    case FileNotAccessibleException.ILLEGAL_NAME:
     throw new Exception("命名規則に違反しています");
    case FileNotAccessibleException.IN_USE:
     throw new Exception("ファイルが使用中です");
    case FileNotAccessibleException.NOT_FOUND:
     throw new Exception("ファイルがありません");
    default:
     throw new Exception("ファイルにアクセスできません");
   }
  } catch (FileSystemFullException e){
   throw new Exception("空き容量がありません");
  } catch (Exception e){
   throw new Exception(e.toString());
  }
 }
 
 /**
  * ファイルの更新
  * @param path string ファイル名
  * @param data byte[] データ
  * @throws Exception
  */
 private void fileUpdate(String path,byte[] data) throws Exception {
  try{
   File file = this.folder().getFile(path);
   this.write(file, data);
  } catch (Exception e){
   throw new Exception("fileUpdate=>" + e.toString());
  }
 }
  
 /**
  * ファイル書き込み
  * @param file File ファイル
  * @param data byte[] データ
  * @throws Exception
  */
 private void write(File file,byte[] data) throws Exception {
  try{
   FileEntity fe = null;
   try{
    fe = file.open(File.MODE_WRITE_ONLY); //書き込みモードで開く
    FileDataOutput fdo = null;
    try{
     //書き込み処理
     fdo = fe.openDataOutput();
     //fdo.writeBytes(body);
     //fdo.writeUTF(body);
     fdo.write(data);
     fdo.flush();
    } catch (Exception e){
     throw new Exception(e.toString());
    } finally{
     fdo.close();
    }
   } catch (Exception e){
    throw new Exception(e.toString());
   } finally{
    fe.close();
   }
  } catch (Exception e){
   throw new Exception(e.toString());
  } finally {
  }
 }
 
 /**
  * ファイルが存在して、読み込み可能かチェック
  * @param path
  * @return boolean 読み込み可否
  * @throws Exception
  */
 private boolean fileCheck(String path) throws Exception {
  FileEntity fe = null;
  try{
   fe = (this.folder().getFile(path)).open(File.MODE_READ_ONLY); //読み込みモードで開く
  } catch (MediaNotFoundException e){
   throw new Exception("SDカードが見つかりません");
  } catch (FileNotAccessibleException e){
   if(e.getStatus() == FileNotAccessibleException.NOT_FOUND) {
    // ファイルが存在しない場合
    return false;
   } else {
    throw new Exception(e.toString());
   }
  } catch (Exception e){
   // エラーなら例外
   throw new Exception("[" + path + "]読込失敗 " + e.toString());
  } finally{
   try{
    fe.close();
   } catch (Exception e) {
    // ファイルがない場合とかはエラーになるので
   }
  }
  
  return true;
 }
 
 /**
  * アクセス制限なしのトークンを取得
  * @return アクセス権を表すインスタンス
  */
 private DoJaAccessToken token() throws Exception {
  if(_token == null){
   try{
    _token = DoJaStorageService.getAccessToken(0,DoJaStorageService.SHARE_APPLICATION);
   } catch (Exception e){
    throw new Exception(e.toString());
   }
  }
  return _token;
 }
 
 /**
  * StorageDevice オブジェクトを取得する
  * @return StorageDevice
  */
 private StorageDevice device() throws Exception {
  if(_device == null){
   try{
    _device = StorageDevice.getInstance(DEVICE_EXT);
   } catch (IllegalArgumentException e){
    throw new Exception("[" + DEVICE_EXT + "]がありません");
   } catch (SecurityException e){
    throw new Exception("ADFで許可されていないか、ロック等、独自のセキュリティで保護されています");
   } catch (Exception e) {
    throw new Exception(e.toString());
   }
  }
  return _device;
 }
 
}