ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »テキストファイル読み込み
このページの記事一覧

【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ  


 これまで色々なテキストファイルの読み込み・保存関数を複数ページに渡って列挙してしまったので、一覧としてまとめてみる。説明等は簡略してあるので、詳細な解説や注意点など必要ならば、各記事を参照して貰いたい。例外処理・確認コードも省略する。定数も一番上の定義を共有とする(デフォルトのエンコードと読み込みバッファサイズのみ)。必要あれば、引数等を付け加えてオーバーロードしても良いだろう。

 これらは、1つのクラスにまとめても良いが、できれば各プラットフォーム用(Android, Applet, 汎用等)に分けて置いた方が無駄がなくて良いかも。

【共通】
ストリームからの読み込み・保存
ローカルシステムから、テキストファイルの読み込み・保存
ストリームからテキストを行読みする(OS依存)
URL経由で外部Webサーバ上(http)のテキストファイルを読み込む(ダウンロードする)
【Android】
res/raw フォルダから、テキストファイルの読み込み
assets フォルダから、テキストファイルの読み込み
内部ストレージから、テキストファイルの読み込み・保存
SDカードから、テキストファイルの読み込み・保存
エラーをSDカードに書き出す(別ページ)
プリファレンス機能で値の読み込み・保存(別ページ)
【Applet】
URL経由で同Webサーバ上のテキストファイルを読み込む
jar ファイル内から、テキストファイルを読み込む


■【共通】 ストリームからの読み込み・保存
//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ


//入力ストリームから読み込み、バイト配列で返す(汎用)
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}


//入力ストリームから読み込み、テキストエンコードして返す(汎用)
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


//出力ストリームにてテキストを保存(汎用)
public static final void saveText(OutputStream outputStream, String text, String charsetName)
throws IOException, UnsupportedEncodingException {
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(outputStream);
bos.write(text.getBytes(charsetName)); //すべての byte[] を取得
bos.flush();
} finally {
try {
bos.close();
} catch (Exception e) {
//IOException
}
}
}

(解説) readStream(), loadText()
(解説) saveText()


■【共通】 ローカルシステム(Windows 等)から、テキストファイルの読み込み・保存
//ローカルシステム(Windows 等)から、テキストファイルを読み込む(汎用)
//(ex) String fileName = "C:/res/data/sample.txt"; //相対パスでも良い
// String text = loadTextLocal(fileName);

public static final String loadTextLocal(String fileName) throws IOException, FileNotFoundException {
InputStream is = new FileInputStream(fileName);
return loadText(is, DEFAULT_ENCORDING);
}


//ローカルシステム(Windows 等)に、テキストファイルを保存(汎用)
//(ex) String fileName = "C:/res/data/sample.txt"; //相対パスでも良い
// String text = "保存するテキスト";
// saveTextLocal(fileName, text);

public static final void saveTextLocal(String fileName, String text) throws IOException {
OutputStream os = new FileOutputStream(fileName);
saveText(os, text, DEFAULT_ENCORDING);
}

(解説) loadTextLocal()


■【共通】ストリームからテキストを行読みする(OS依存)
/**<h1>ストリームからテキストを行読みする(行セパレータを指定)</h1>
* <p>行末にセパレータを付ける。エンコードはシステム依存となる。</p>
* @param is : 入力ストリーム
* @param lineSep : 行セパレータ("\n" など)
* @return<b>String</b> : 読み込んだテキスト
* @throws IOException
*/
public static final String readLinesText(final InputStream is, final String lineSep) throws IOException {
final StringBuilder str = new StringBuilder();
final BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
while (br.ready()) {
str.append(br.readLine()); //終端文字は含まない
str.append(lineSep); //改行コードなど
}
return str.toString();
} finally {
br.close();
str.setLength(0);
}
}

/**<h1>ストリームからテキストを行読みする(OS依存の改行が付く)</h1>
* <p>行末にセパレータ(改行)を付ける。エンコードはシステム依存となる。</p>
* @param is : 入力ストリーム
* @return<b>String</b> : 読み込んだテキスト
* @throws IOException
*/
public static final String readLinesText(final InputStream is) throws IOException {
return readLinesText(is, System.getProperty("line.separator")); //OS依存 改行コード
}


/**<h1>行ごとに文字列を読み込んでリストで返す(OS 依存)</h1>
* <p>各要素の終端は改行を含まない。</p>
* @param is : 入力ストリーム
* @return<b>List<String></b> : 行ごとの文字列
* @throws IOException
*/
public static final List<String> readLinesList(final InputStream is) throws IOException {
final List<String> list = new ArrayList<String>();
final BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
while (br.ready()) {
list.add(br.readLine()); //終端文字は含まない
}
return list;
} finally {
br.close();
}
}

(解説) readLinesText()


■【Android】 res/raw フォルダから、テキストファイルの読み込み
// res/raw フォルダから、リソース名でテキストファイルを読み込む(Android 用)
//(ex) String resName= "sample"; // "res/raw/sample.txt" の場合
// String text = loadTextRaw(resName, this); //this は起動 Activity 等(Context)

public static final String loadTextRaw(String resName, Context context) throws IOException, FileNotFoundException {
final int id = context.getResources().getIdentifier(resName, "raw", context.getPackageName());
if (id == 0) { //エラーにはならない
throw new FileNotFoundException();
}
InputStream is = context.getResources().openRawResource(id);
return loadText(is, DEFAULT_ENCORDING);
}


// res/raw フォルダから、リソースID でテキストファイルを読み込む(Android 用)
//(ex) int rawId = R.raw.text; // "res/raw/sample.txt" の場合
// String text = loadTextRaw(rawId, this); //this は起動 Activity 等(Context)

public static final String loadTextRaw(int rawId, Context context) throws IOException, FileNotFoundException {
if (rawId == 0) {
return null;
}
InputStream is = context.getResources().openRawResource(rawId);
return loadText(is, DEFAULT_ENCORDING);
}

(解説) loadTextRaw()


■【Android】 assets フォルダから、テキストファイルの読み込み
// assets フォルダから、テキストファイルを読み込む(Android 用)
//(ex) String fileName = "res/data/sample.txt"; // assets/ 以下の相対パス
// String text = loadTextAsset(fileName, this); //this は起動 Activity 等(Context)

public static final String loadTextAsset(String fileName, Context context) throws IOException, FileNotFoundException {
final AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open(fileName);
return loadText(is, DEFAULT_ENCORDING);
}

(解説) loadTextAsset()


■【Android】 内部ストレージから、テキストファイルの読み込み・保存
// 内部ストレージから、テキストファイルを読み込む(Android 用)
//(ex) String fileName = "sample.txt"; // "data/data/[パッケージ名]/files/sample.txt" になる
// String text = loadTextLocalStorage(fileName, this); //this は起動 Activity 等(Context)

public static final String loadTextLocalStorage(String fileName, Context context)
throws IOException, FileNotFoundException {
InputStream is = context.openFileInput(fileName);
return loadText(is, DEFAULT_ENCORDING);
}


//内部ストレージに、テキストファイルを保存する(Android 用)
// (ex) String fileName = "sample.txt"; // "data/data/[パッケージ名]/files/sample.txt" となる
// String text = "保存するテキスト";
// saveTextLocalStorage(fileName, text, this); //this は起動 Activity 等(Context)

public static final void saveTextLocalStorage(String fileName, String text, Context context) throws IOException {
// "data/data/[パッケージ名]/files/" 直下に保存。他アプリアクセス不可(MODE_PRIVATE)
OutputStream os = context.openFileOutput(fileName, Context.MODE_PRIVATE);
saveText(os, text, DEFAULT_ENCORDING);
}

(解説) loadTextLocalStorage()
(解説) saveTextLocalStorage()


■【Android】 SDカードから、テキストファイルの読み込み・保存
(※) Android4.4(API 19)あたりから内部ストレージの仮想パスに変わった模様
// SDCard のマウント状態のチェックする(Android 用)
public static final boolean isMountSDCard() {
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
return true; //マウントされている
} else {
return false; //マウントされていない
}
}

// SDCard のルートディレクトリを取得(Android 用)
public static final File getSDCardDir() {
return Environment.getExternalStorageDirectory();
}

// SDCard 内の絶対パスに変換(Android 用)
public static final String toSDCardAbsolutePath(String fileName) {
return getSDCardDir().getAbsolutePath() + File.separator + fileName;
}


// SDCard から、テキストファイルを読み込む(Android 用)
//(ex) String fileName = "sample.txt"; // "mnt/sdcard/sample.txt" or "sdcard/sample.txt" になる(端末による)
// String text = loadTextSDCard(fileName);

public static final String loadTextSDCard(String fileName) throws IOException {
if (!isMountSDCard()) { //マウント状態のチェック
throw new IOException("No Mount");
}
final String absPath = toSDCardAbsolutePath(fileName); //SDCard 内の絶対パスに変換
InputStream is = new FileInputStream(absPath);
return loadText(is, DEFAULT_ENCORDING);
}


//SDCard に、テキストファイルを保存する(Android 用)
// (ex) String fileName = "sample.txt"; // "mnt/sdcard/sample.txt" or "sdcard/sample.txt" になる(端末による)
// String text = "保存するテキスト";
// saveTextSDCard(fileName, text);

public static final void saveTextSDCard(String fileName, String text) throws IOException {
if (!isMountSDCard()) {
throw new IOException("No Mount");
}
final String absPath = toSDCardAbsolutePath(fileName); //SDCard 内の絶対パスに変換
OutputStream os = new FileOutputStream(absPath);
saveText(os, text, DEFAULT_ENCORDING);
}

(解説) loadTextSDCard(), isMountSDCard(), toSDCardAbsolutePath(), getSDCardDir()
(解説) saveTextSDCard()
(解説) saveText()


■【共通】 URL経由で外部Webサーバ上(http)のテキストファイルを読み込む(ダウンロードする)
//URL経由でWebサーバ上(http)のテキストファイルを読み込む(Android, Applet, 汎用)
//(ex) String httpUrl = "http://www.xxx.com/sample.txt"; //WebサイトのURL(http)
// String text = loadTextHttp(httpUrl, "UTF-8", 10000); //Timeout:10秒
//(Android) <uses-permission android:name="android.permission.INTERNET" /> が必要。

public static final String loadTextHttp(String httpUrl, String charsetName, int connectTimeout)
throws SocketTimeoutException, IOException {
final URL url = new URL(httpUrl);
final HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.setConnectTimeout(connectTimeout); //接続タイムアウト
con.setRequestMethod("GET");
con.connect();
InputStream is = con.getInputStream();
return loadText(is, DEFAULT_ENCORDING);
}

(参考) JSON を PHP から送信して、Java で受信する
(参考) 画像を PHP から送信して、Android で受信する


■【Applet/汎用】 URL経由で同Webサーバ上のテキストファイルを読み込む
//URL経由でWebサーバ上のテキストファイルを読み込む(Applet, 汎用)
//(ex) String fileName = "res/data/sample.txt"; //html からの相対パス
// String text = loadTextURL(new URL(getCodeBase(), fileName)); //同サーバ上の場合

public static final String loadTextURL(URL url) throws IOException {
InputStream is = url.openStream();
return loadText(is, DEFAULT_ENCORDING);
}

(解説) loadTextURL()


■【Applet】 jar ファイル内から、テキストファイルを読み込む
//クラスから自身の jar の URL を取得する(jar 内の .class からのみ)
public static final URL getJarFileURL(Object object) {
try {
final ClassLoader loader = object.getClass().getClassLoader();
final String name = object.getClass().getName().replace('.', '/') + ".class";
final URL url = loader.getResource(name);
final Pattern p = Pattern.compile("^jar\\:(.+?\\.jar)\\!\\/(.*)");
final Matcher m = p.matcher(url.toString());
if (m.matches()) {
final MatchResult res = m.toMatchResult();
return new URL(res.group(1));
}
} catch (Exception e) {
//MalformedURLException, ClassCastException, NullPointerException, ...
}
return null; //取得失敗した場合はすべて null
}

//ファイルパスから jar 内のリソース URL を作成する
public static final String toJarURL(String fileName, Object context) {
final URL url = getJarFileURL(context); //jar の url を取得
if (url == null) {
return null; //失敗
}
return "jar:" + url.toString() + "!/" + fileName; //JAR URL 構文にするだけ
}


//jar ファイル内から、テキストファイルを読み込む(Applet 用)
//(ex) String fileName = "res/data/sample.txt"; //jar 内相対パス
// String text = loadTextJar(fileName, this); //this は起動 Applet 等(jar 内の .class)

public static final String loadTextJar(String fileName, Object context) throws IOException, FileNotFoundException {
final String jarUrl = toJarURL(fileName, context);
if (jarUrl == null) { //見つからないとき
throw new FileNotFoundException();
}
final URL url = new URL(jarUrl);
InputStream is = url.openStream();
return loadText(is, DEFAULT_ENCORDING);
}

(解説) getJarFileURL()
(解説) toJarURL()
(解説) loadTextJar()


 Android のプリファレンス機能を使って読み込みや保存をするには→こちら


(関連記事)
【Android】エラーをSDカードに書き出す
【Android】Preference 機能を使ってデータを読み込み・保存する
【Android】assets フォルダから画像ファイルを読み込む
【Android】SDカードから画像ファイルを読み込む
【Android】SDカードに画像ファイルを保存する(png)
【Android】SDカードに画像ファイルを保存する(jpg)
【Android】内部ストレージから画像ファイルを読み込む
【Android】内部ストレージに画像ファイルを保存する(png)
【Android】内部ストレージに画像ファイルを保存する(jpg)



スポンサーサイト

category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み  テキストファイル保存 
tb: 0   cm: --

【Android】【Java】SDカードからテキストファイルを読み込む  


 今度は Android の外部ストレージ(SDカード)からテキストファイルを読み込んでみる。エミュレータで試したいときはSDカードのマウントが必要なので、以下のHPあたり参考にすると良いだろう。上手く行かなければコマンドラインで起動する手もある。

(参考) Androidエミュレーターの仮想SDカードを使う
(参考) SDカードをマウントしてエミュレーターを起動

 上手くマウントできたなら、DDMS でも確認できる。マウントフォルダは Android端末によって異なるが、「/sdcard」や「/mnt/sdcard」辺りを覗いて見ればわかるだろう。もしファイルがあれば、DDMS の右上あたりにある [push]ボタンでファイル転送、[pull] ボタンで開発環境にファイルをコピーもできる。

 コードは今までよりも少し多くなる。と言っても基本は変わらないのだが、SDカードは脱着が容易なため、常にマウントの状態を確認しなければならない。それと先ほど述べたように、端末によってルートディレクトリが違うので、動的に取得する必要がある。その辺のコードが少し加わっただけだ。

 ストリームからのテキストファイル読み込みは例によって以前作ったものをそのまま使う。

 loadText() - ストリームからテキストファイルを読み込む

 手順を簡単に説明すると、次のようになる。

1.SDカードのマウント状態やルートディレクトリを調べる。
2.SDカードの入力ストリームを開く。
3.ストリームからテキストエンコーディングして文字列を返す。


●SDカードの入力ストリームを開く部分 [Android 用]
(※) Android4.4(API 19)あたりから内部ストレージの仮想パスに変わった模様
//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード


// SDCard のマウント状態をチェックする(Android 用)
public static final boolean isMountSDCard() {
final String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
return true; //マウントされている
} else {
return false; //マウントされていない
}
}

// SDCard のルートディレクトリを取得(Android 用)
public static final File getSDCardDir() {
return Environment.getExternalStorageDirectory();
}

// SDCard 内の絶対パスに変換(Android 用)
public static final String toSDCardAbsolutePath(String fileName) {
return getSDCardDir().getAbsolutePath() + File.separator + fileName;
}


// SDCard から、テキストファイルを読み込む(Android 用)
public static final String loadTextSDCard(String fileName) throws IOException {
if (!isMountSDCard()) { //マウント状態のチェック
throw new IOException("No Mount");
}
InputStream is = new FileInputStream(toSDCardAbsolutePath(fileName));
return loadText(is, DEFAULT_ENCORDING);
}


//メインでは... (※例外処理は省略)
String fileName = "sample.txt"; //"mnt/sdcard/sample.txt" or "sdcard/sample.txt" 等になる(端末による)
String text = loadTextSDCard(fileName);
System.out.println(text); //Log.d("tag", text); でも良い

 マウント状態のチェックでは IOException() にメッセージを付けてあるが、判別しずらければ、他の Exception に変えたほうが良いかも知れない。本来なら外部ストレージの状態は様々な定数で表現されているのだが、ここではとりあえず、マウントだけをチェックしている。必要があれば、色々チェックしても良いだろう。

●ストリームからテキストエンコーディングして読み込む部分 [汎用](- loadText() ※以前作ったものを使い回し)
//設定値
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ

//ストリームから読み込み、バイト配列で返す
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}

//ストリームから読み込み、テキストエンコードして返す
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


 次回は SDカードへの書き込みも考えてみよう。と言ってもこれまでのものを組み合わせると簡単にできる。

 テキストファイルの読み込みや保存をまとめたページは→こちら


(関連記事)
【Android】SDカードにテキストファイルを保存する
【Android】エラーをSDカードに書き出す
【Android】SDカードから画像ファイルを読み込む
【Android】SDカードのファイルを削除する
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する



category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み  SDカード 
tb: 0   cm: --

【Android】【Java】内部ストレージからテキストファイルを読み込む  


 Android には「内部ストレージ」というアプリケーションごとにデータを保存できる場所がある。そのファイルは、端末の「/data/data/[パッケージ名]/files/」に置かれる。Eclipse を使っているのなら、「DDMS」に切り替えれば見れるだろう(エミュレータを起動している時のみ)。与えるパーミッションによっては他のアプリからも読めるが、通常はセキュリティを考えて、各アプリ固有のファイルに設定する。アプリケーション間でデータを共有したい場合は、ContentProvider の機能を使う。

 Context クラスの getDir() など、Android 専用のメソッドで、配下にフォルダなども作れるが、「/data/data/[パッケージ名]/app_[フォルダ名]/」のように一定形式で作られるので、それに準拠してないと上手く読めない恐れがある。大量のファイルを管理するのには向いてないかも知れない。とりあえず、そのアプリ固有のデフォルトの保存場所での使い方。

 ストリームからのテキストファイル読み込みは例によって以前作ったものをそのまま使う。

 loadText() - ストリームからテキストファイルを読み込む

 手順を簡単に説明すると、次のようになる。

1.内部ストレージ(ローカルストレージ)の入力ストリームを開く。
2.ストリームからテキストエンコーディングして文字列を返す。


●内部ストレージの入力ストリームを開く部分 [Android 用]
//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード

//内部ストレージから、テキストファイルを読み込む(Android 用)
public static final String loadTextLocalStorage(String fileName, Context context)
throws IOException, FileNotFoundException {
InputStream is = context.openFileInput(fileName); // "data/data/[パッケージ名]/files/" 直下
return loadText(is, DEFAULT_ENCORDING);
}

//メインでは... (※例外処理は省略)
String fileName = "sample.txt"; // "data/data/[パッケージ名]/files/sample.txt" になる
String text = loadTextLocalStorage(fileName, this); //this は起動した Activity が良い(Context)
System.out.println(text); //Log.d("tag", text); でも良い

 DDMS で覗いて、保存フォルダが作られていれば、右上の方にある [push] ボタンからファイル転送もできるが、無い場合は、Context クラスの openFileOutput() で書き込めばフォルダが自動的に作られる。

●ストリームからテキストエンコーディングして読み込む部分 [汎用](- loadText() ※以前作ったものを使い回し)
//設定値
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ

//ストリームから読み込み、バイト配列で返す
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}

//ストリームから読み込み、テキストエンコードして返す
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


 ついでなので、次回は内部ストレージにテキストファイルを保存してみよう。

 テキストファイルの読み込みや保存をまとめたページは→こちら


(関連記事)
【Android】内部ストレージにテキストファイルを保存する
【Android】内部ストレージから画像ファイルを読み込む
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】SDカードからテキストファイルを読み込む
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する



category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み  内部ストレージ 
tb: 0   cm: --

【Android】【Java】assets フォルダからテキストファイルを読み込む  


 今回は Android プロジェクトでのもう1つのリソース保管場所「assets」フォルダからテキストファイルを読み込んでみる。前回の「raw」フォルダとの大きな違いは、assets フォルダに関しては、ADT がリソースIDを割り振らないという点がある。つまり「R.id.~」「R.raw.~」のような int 定数では表現できないという事だ。しかし逆に言えば、「res/raw/」フォルダと違って、自由にフォルダ階層を作れるわけで(ADT が管理している場合、自由にフォルダ名などは決められない)、慣れてしまえば assets の方が汎用性は高いだろう。読み込み方も AssetManager という専用のオブジェクトが Android システムにはあるので、非常に簡単だ。

 ストリームからのテキストファイル読み込みは例によって以前作ったものをそのまま使う。。

 loadText() - ストリームからテキストファイルを読み込む

 手順を簡単に説明すると、次のようになる。

1.AssetManager を取得する。
2.assets フォルダの入力ストリームを開く。
3.ストリームからテキストエンコーディングして文字列を返す。


●assets フォルダの入力ストリームを開く部分 [Android 用]
//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード

//assets フォルダから、テキストファイルを読み込む(Android 用)
public static final String loadTextAsset(String fileName, Context context) throws IOException {
final AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open(fileName);
return loadText(is, DEFAULT_ENCORDING);
}


//メインでは... (※例外処理は省略)
String fileName = "res/data/sample.txt"; // "assets/res/data/sample.txt" となる
String text = loadTextAsset(fileName, this); //this は起動した Activity が良い(Context)
System.out.println(text); //Log.d("tag", text); でも良い

 assets フォルダ以下に 「res/data/」 とフォルダを作った場合、ファイル名は "res/data/sample.txt" で表現できる。これは一般的なファイルシステムと同じだ。だから他のプラットフォームへの移植も考慮に入れた場合、初めからここをリソースフォルダとしてコードを書いた方が流用性は高い。ただし、Android 用の言語切り替えなどのローカライズ機能は使えなくなってしまうけどね。ADT の管理下から外れる分、自由に使えるが、Android に初めからビルトインされている機能も管轄外と考えれば良いね。どちらを使うかは自分次第(笑)。

●ストリームからテキストエンコーディングして読み込む部分 [汎用](- loadText() ※以前作ったものを使い回し)
//設定値
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ

//ストリームから読み込み、バイト配列で返す
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}

//ストリームから読み込み、テキストエンコードして返す
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


 次は Android の内部ストレージからテキストファイルを読み込んでみよう

 テキストファイルの読み込みや保存をまとめたページは→こちら


(関連記事)
【Android】assets フォルダから画像ファイルを読み込む
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する


category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み  assets 
tb: 0   cm: --

【Android】【Java】res/raw リソースフォルダからテキストファイルを読み込む  


 今回からはこれまでの Applet 等でのテキストファイル読み込みを Android に応用する。と言ってもやり方はほとんど変わらないので、応用というより流用に近いだろう。ストリームを開いてテキストエンコーディングすると言う基本は同じだ。その主要コードは以前のものを参照して貰いたい。もちろんコピペで構わない。

 loadText() - ストリームからテキストファイルを読み込む

 Android プロジェクト(ADT - Eclipse で開発を想定)ではリソース用のフォルダがあって、その中に汎用の「raw」フォルダがある。普段このフォルダは音声ファイルやビデオファイルなどを入れる事が多いのだが、テキストファイルでも構わない。またここは ADT がリソースID を管理してくれるので、「R.raw.~」のような int 定数でも表現できる。

 しかし今回のコードはそのリソースIDは動的に取得して、引数ではリソースの名前で受け取るようにしよう。わざわざそうした理由は、あくまで汎用性を考慮して、あとで使い回しやすいようなコードにして置くためだ。それは例えば後になって、そのリソースファイルの場所を「res」フォルダ以外に移動する等の場合だ。「R.id.~」「R.drawable.~」のような表記は一般的なものではない。だから他の ADT が ID を割り当ててない場所に移動した場合は使用できなくなる(assets フォルダとか)。つまりコード書き換えが必要になる。リソース名もそれは同じだが、今までのコードの引数がファイルパス名:String 型で作ってあるので、リソースID:int 型よりは融通が利くだろう。もちろん用途が限定しているなら、リソースID表記に書き換えても構わない。

●リソース名から res/raw フォルダの入力ストリームを開く [Android 用]
//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード

// res/raw フォルダから、テキストファイルを読み込む(Android 用)
public static final String loadTextRaw(String resName, Context context) throws IOException, FileNotFoundException {
final int id = context.getResources().getIdentifier(resName, "raw", context.getPackageName());
if (id == 0) { //エラーにはならない
throw new FileNotFoundException();
}
InputStream is = context.getResources().openRawResource(id);
return loadText(is, DEFAULT_ENCORDING);
}


//メインでは... (※例外処理は省略)
String resName = "sample"; // "res/raw/sample.txt" の場合
String text = loadTextRaw(resName, this); //this は起動した Activity が良い(Context)
System.out.println(text); //Log.d("tag", text); でも良い

 Android では、文字エンコーディングは "UTF-8" が推奨なので固定で良いだろう。Windows 環境での開発の場合は、テキストファイルがデフォルトで "Shift_JIS" になってる場合があるので注意。Eclipse での開発の場合は「ウィンドウ」メニューから「設定」-「一般」-「ワークスペース」-「テキスト・ファイルのエンコード」で "UTF-8" を設定して置いた方が良いかもしれない。

 上記の例ではリソース名からIDを引いているが、もちろん R.raw.~ のID (int 型)をそのまま用いても良い。ただし、ID = 0 だけはファイルは見つからないので、そこだけチェックしておくと良いだろう。その場合は以下のようになる。

●リソースIDから res/raw フォルダの入力ストリームを開く [Android 用]
// res/raw フォルダから、テキストファイルを読み込む(Android 用)
public static final String loadTextRaw(int rawId, Context context) throws IOException, FileNotFoundException {
if (rawId == 0) {
return null;
}
InputStream is = context.getResources().openRawResource(rawId);
return loadText(is, DEFAULT_ENCORDING);
}


//メインでは... (※例外処理は省略)
String text = loadTextRaw(R.raw.text, getApplicationContext()); // "res/raw/sample.txt" の場合(第2引数はthisでも良い(Context))
System.out.println(text); //Log.d("tag", text); でも良い

 なお、どちらもテキストにエンコードする部分は以下の関数を使う。

●ストリームからテキストエンコーディングして読み込む部分 [汎用](- loadText() ※以前作ったものを使い回し)
//設定値
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ

//ストリームから読み込み、バイト配列で返す
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}

//ストリームから読み込み、テキストエンコードして返す
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


 確認には「System.out.println()」を使っているが、Android 用の「Log.d("tag", text)」でも構わない。実は、System.out でも LogCat には表示される。しかし、他のプラットフォーム併用まで考えると、System.out の方が便利な気がする。
ちなみに LogCat に付いている「保管済みフィルター」の [+] ボタンを押して、「by Log Tag:」の項目に「System.out」と登録しておくと、Log 出力中に「System.out」のみを表示できる。Log クラスの debug や info 等のレベル、または独自タグなどでもフィルタリングはできるが、「System.out」は他の情報が混ざらない点と、引数が少なく、様々な型に対応してるので(オブジェクトを適当につっこんでも、勝手に toString() してくれるので)、実は意外と使い易かったりする(笑)。もちろん、本題には全く影響しないので、どちらでも好きな方で構わない。

 まだまだ Android には様々なファイル保管場所があるので、次は、assets フォルダからのテキストファイル読み込みを試してみよう。

 テキストファイルの読み込みや保存をまとめたページは→こちら


(関連記事)
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する



category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop