RandomAccessFile ~Shif-JISで読み込む

 RandomAccessFile では、文字コードの指定はできない。
 Shift-JISも扱いたいので、別項のソースに手を加えてみたよ。

	public long head_pos = 0;	//現在のseekヘッド位置

	public String readline_RA( String path, long readPos, String code ) {
//	Log.d("TEST", "readline_RA : "+path );

		String result = "";
		//--

		try{
			File file = new File( path );
			RandomAccessFile ra = new RandomAccessFile( file, "r" );
			ra.seek( readPos );

			String str = ra.readLine();
			if ( str!= null ){
				result = str;
			//	}else{
				//	result = "";
				//	Log.d("Err", "// readline_RA : read is null //" );
			}
			head_pos = ra.getFilePointer();

			//
			if ( code != "UTF-8" ){
				// 改行コード判定
				//	CR : 0x0D : \r
				//	LF : 0x0A : \n
				//	UNIX = LF : Mac = CR : DOS = CR+LF

				byte[] buffer = new byte[ 2 ];	// 行末2バイトを読み込む
				ra.seek( head_pos -2 );
				ra.read(buffer);
				long RT = 1;
				if ( ( buffer[0] == 0x0D )&&( buffer[1] == 0x0A ) ){	//DOS
					RT = 2;
				}
				//--

				ra.seek( readPos );
				buffer = new byte[ (int)( head_pos -RT -readPos ) ];	// 読み込む量
				int r = ra.read(buffer);
				if ( -1 != r ){
					result = new String( buffer, code );
				}
			}
			//--

			ra.close();
		}catch( Exception e ){
			Log.d("Err", "// readline_RA : read ERR //" );
		}
		
		//--
		return result;
	}

仕組み

 手を加えた部分のは、23行~46行。

	1. readLine で読み込んだ範囲を、byte 配列で読み込み直す。
	2. byte 配列を文字コードを指定して、String に変換。

 readLine のデータを直接変換するのがシンプルなんだけど…。
 そのデータは、すでにUTF-8のためのbyte を差し挟まれちゃってる。
 そんなbyte 配列をプレーンな状態にするより、もう一度読み込んだ方が、結果的にシンプルなんだよね。
 直接変換するようなものがあるのかもしれないけど。

 だもんで、readLine は「一行の範囲を調べる」だけになってる。(^_^;

読み込み範囲

 最初の位置からgetFilePointer までを読み込むと、改行コードがbyte 配列に含まれてしまう。
 これをそのままTextView へ表示すると、不明文字のトウフが表示されちゃう。
 それは都合がわるいので、改行コードを調べて、読み込み範囲を補正する必要がある。(30~36行目)
 調べた値は long RT に格納し、読み込み範囲の補正に使っている(39行目)

文字コード指定

 指定した文字コードで変換するのは、難しくない。
 byte から、文字コードを指定して、String を作るだけ。(43行目)

	result = new String( buffer, code );

by the way…

 引数 code は、String で文字コードを指定することにしている。
 シフトJISなら、”Shift_JIS”。
 試してないけど、EUC-JPにも対応してるハズ。

Posted in File, 読み込み. Tags: , , . RandomAccessFile ~Shif-JISで読み込む はコメントを受け付けていません »

RandomAccessFile ~ファイルの読み込み

 ファイルを扱うclass は色々あるね。
 今回はRandomAccessFile を使ってみたよ。

RandomAccessFile の利点

 RandomAccessFile を使うと、読み込み位置なんかを指定できるんだ。
 これはゲームの再開なんかに、とても都合がいい。

RandomAccessFile での読み込み

 下記サンプルでは、テキスト・ファイルを一行読み込みしている。

	public long head_pos = 0;	//現在のseekヘッド位置

	public String readline_RA( String path, long readPos, String code ) {
//	Log.d("TEST", "readline_RA : "+path );

		String result = "";
		//--

		try{
			File file = new File( path );
			RandomAccessFile ra = new RandomAccessFile( file, "r" );
			ra.seek( readPos );

			String str = ra.readLine();
			if ( str!= null ){
				result = str;
			//	}else{
				//	result = "";
				//	Log.d("Err", "// readline_RA : read is null //" );
			}
			head_pos = ra.getFilePointer();

			ra.close();
		}catch( Exception e ){
			Log.d("Err", "// readline_RA : read ERR //" );
		}
		
		//--
		return result;
	}

モード設定

 RandomAccessFile は書き込み、読み込みで、別class になっていない。
 そのため、オブジェクト生成時に、モードを設定する必要がある。
 下記では、読み込み専用として生成している。

	new RandomAccessFile( file, "r" );

位置設定

 書き込み位置、読み込み位置の設定は、seek method を使う。
 値はlong で指定する。

	seek( readPos );

位置の取得

 書き込み位置、読み込み位置の取得は、getFilePointer method を使う。
 値はlong 。

	getFilePointer();

by the way…

 RandomAccessFile では、文字コードの指定はできない。
 そのためテキストファイルは、デフォルト・コード(UTF-8)で扱われてしまう。
 Shift-JISを扱うには、別途自前で直す必要がある。
 コレに関しては、別項・

Shif-JISで読み込む
にて。

Posted in File, 読み込み. Tags: , . RandomAccessFile ~ファイルの読み込み はコメントを受け付けていません »

リソースからのファイルコピー

 エミュレータにテスト・ファイルを送りたい。
 WebからDownLoadする、コンソールからwgetする…?
 いろいろやり方はあるけど、リソースからコピーできると便利。
 「デモファイルのインストール」なんて機能にもなるしね。

 やり方はシンプルなコピーとそう変わりがない。
 リソースのpathを取得するには、Resources class を使うのだが。
 このResources からは、InputStream しか生成できない。
 そのため、FileChannel は使えないんだ。

 下記サンプルでは、SDカードのルートにファイルをコピーしている。

	public void cpResTo_SD( Context context, int res_id, String fName ) {
		
		// Copy先の取得
		File cpFile = new File( Environment.getExternalStorageDirectory().getPath()+"/" +fName );
//	Log.d( "TEST", "copy to :" +cpFile.getPath() );
	
		// exec copy
		try{
			
			Resources res = context.getResources();
			
			InputStream is = res.openRawResource( res_id );
			OutputStream os = new FileOutputStream( cpFile );

			byte[] buffer = new byte[ 1024*4 ];	// 1024*4 = DEFAULT BUFFER SIZE
			int r = 0;
			while( -1 != ( r = is.read(buffer)) ){
				os.write( buffer, 0, r );
			}

			is.close();
			os.close();
			
		}catch( Exception ex ){
			Log.d( "TEST", "/res -> copy error..." );
		}
		//--
	}

 DEFAULT BUFFER SIZE が 1024*4 となっているのは、ファイルの最小サイズが4kだから。
 これより大きくても、小さくても問題ないけど、4kにしておくのが一番、効率がいい。

 注意点としては、リソースの場所があげられる。
 たとえばテキスト・ファイルなんかを、/values に格納するとeclipse でエラーとなる。
 /raw なんかを作り、そこに格納しておく必要がある。

Posted in File, コピー. Tags: , , . リソースからのファイルコピー はコメントを受け付けていません »