스마트기기개발관련/안드로이드 개발

[안드로이드] android res/raw 에서 파일 읽기쓰기 관련

AlrepondTech 2013. 8. 19. 17:27
반응형


/////



file io


http://blog.naver.com/PostView.nhn?blogId=hwan2s&logNo=20162242450



ctivity

package com.oks.app;


import java.io.FileInputStream;

import java.io.FileOutputStream;


import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

import android.widget.Toast;


import com.dhrod0325.R;


public class AppstudyActivity extends Activity {

private Button btnSavebtnLoad;

private EditText editText;

private TextView textView;


@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);


btnSave = (Button) findViewById(R.id.save);

btnSave.setOnClickListener(clickListener);

btnLoad = (Button) findViewById(R.id.load);

btnLoad.setOnClickListener(clickListener);

textView = (TextView)findViewById(R.id.textView1);

editText = (EditText) findViewById(R.id.editText1);

}


View.OnClickListener clickListener = new View.OnClickListener() {

public void onClick(View v) {

switch (v.getId()) {

case R.id.save:

try {

FileOutputStream fos = openFileOutput("test.txt",MODE_PRIVATE);

String str = editText.getText().toString();

fos.write(str.getBytes());

fos.close();

Toast.makeText(getApplicationContext(), "writeComplate",Toast.LENGTH_SHORT).show();

catch (Exception e) {

e.printStackTrace();

}

break;

case R.id.load:

try {

FileInputStream fis = openFileInput("test.txt");

byte[]data = new byte[fis.available()];

while(fis.read(data)!=-1){;}

fis.close();

textView.setText(new String(data));

catch (Exception e) {

e.printStackTrace();

}

break;

default:

break;

}

}

};

}


xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical"

    android:id="@+id/layout" >


    <EditText

        android:id="@+id/editText1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" 

        android:hint="android file io test">


        <requestFocus />

    </EditText>


    <Button

        android:id="@+id/save"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="save" />

    

    <Button

        android:id="@+id/load"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="load" />


    <TextView

        android:id="@+id/textView1"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="TextView" />


</LinearLayout>



파일을 미리 안드로이드에 포함시켜 놓고 읽기 위한 설정

res/raw 폴더 추가 하고 안에다 파일 위치

그리고 읽음


public String onRawFile(){

String readData;

try {

InputStream fis = getResources().openRawResource(R.raw.rawfile);

byte[] data = new byte[fis.available()];

while(fis.read(data)!=-1){;}

readData = new String(data);

catch (IOException e) {

readData = "failed read";

e.printStackTrace();

}

return readData;

}



출처 : http://dhrod0325.blog.me/140160580872




//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

우리는 /res/raw 폴더에 있는 sample.txt를 읽는것을 목표로 할것이다.

 

우선, 기본 구조는 다음과 같다.

손가락 꾹

protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 
 
  new Thread( new Runnable() {
   
   @Override
   public void run() {
    // TODO Auto-generated method stub
    loadTxt();
   }
  }).start();

 

 

btn1.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    printAll(arraylist);
   }
  });


 }

onCreate에서 Thread를 하나 생성하고 loadTxt()라는 함수를 불러서 파일을 읽을것이다.

왜 그냥 loadTxt를 부르지 않고 thread를 하나 생성하는지는

http://mantdu.tistory.com/entry/안드로이드-thread-생성onCreate함수에서-txt읽기 를 읽어보기 바란다.

 

loadTxt함수는 다음과 같이 구현한다.

public void loadTxt(){
  InputStream inputData = getResources().openRawResource(R.raw.sample);
  
  arraylist = new ArrayList<String>();
  
  try {
   BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(inputData,"EUC_KR"));
   while(true){
    String string= bufferedReader.readLine();    
   
    if(string != null){
     arraylist.add(string);
    }else{     
     
     break;
    }
   }
  
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 

함수 내에서는 AarryList<String> 객체를 만들어준다.

이 arraylist에다가 BufferedReader를 생성해서 한줄씩 읽어와야하는데 그부분은

BufferedReader bufferedReader= new BufferedReader(new InputStreamReader(inputData,"EUC_KR"));
이렇게 선언을 한다. new BufferedReader의 입력변수값은 'in'인데 우리는 InputStreamReader를 이용한 inputData객체의 값을 읽어오기때문에 위와 같이 사용한다.

그다음은 무한루프를 돌면서 버퍼드리더의 readLine()함수를 이용해서 한줄을 읽고 arraylist.add(string)을 이용해서 읽은 값을 ArrayLIst에 저장한다. 이때 readLine()은  '\n''\r'"\r\n"  과 같이 캐리지리턴 값과 함께 한 줄을 리턴한다.

 

tip>여기서 BufferedRead buff......와 String string = buff... 는 throw혹은 try-catch로 감싸줘야하는데 이때

 



왼쪽 그림과 같이 두개의 try-catch를 쓸 수도 있겠지만 bufferedReader를 선언할때 catch되어야 하는 unsupportedEncodingException은 api를 들여다 보면 java.io.IOException이고, bufferedRader.readLine()의 익셉션 역시 IOException이므로, 오른쪽 그림과 같이 공통된 상위 exception인 IOException e 하나로 묶을 수 있다~.

 

 

 

다시 onCreate로 넘어가보자

@Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 
  text1 = (TextView)findViewById(R.id.textview1);
  btn1= (Button)findViewById(R.id.button1);
  
  new Thread( new Runnable() {
   
   @Override
   public void run() {
    // TODO Auto-generated method stub
    loadTxt();
   }
  }).start();
  
  btn1.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    printAll(arraylist);
   }
  });
   
 }

이제 화면에서 button을 누르면 텍스트파일의 내용이 출력되게 만들것이다.

그러기 위해서 btn1의 객체를 생성하고 OnclickListener를 추가해준다.

만약 버튼이 눌리면 printAll(arraylist)라는 함수가 실행된다.

 

public void printAll(ArrayList<String> array){
  int i=0;
  while(true){   
   if(i>=array.size()){
    break;
   }else if(array.get(i) != null){
    text1.append(array.get(i++)+"\n");
   }
  }
 }

해당 함수는 위와 같이 구현하였다.

무한루프를 돌면서 매번 array.get(int i)로 ArrayList Data를 불러오고 text1에 append한다. 이 작업을 하면서 매번 array.size()로 배열 크기를 초과하는지 체크를하고, 배열크기보다 카운트가 커지면 함수가 종료되게 만들었다.

이 부분을 구현하면서 짜증..났던점은 array.size().......... 사이즈 체크 잘 안하면 exception이 발생합니다.

IndexOutOfBoundsException - 인덱스가 범위외의 경우 (index < 0 || index > size())

 

 

---------------------------------------------

정리

inputStream -> bufferedReader -> ArrayList의 readLine()

 

체크

txt파일은  프로젝트/res/raw폴더에 위치해 있어야 합니다. 만약 raw폴더가 없다면 새로 생성해 주면 됩니다!

 

체크2.매우중요

왜 버튼을 눌르면 뜨게 구현하였느냐? 그냥 바로 띄우면 안되냐?

이 이유는 thread에 있습니다.

http://mantdu.tistory.com/entry/안드로이드-thread-생성onCreate함수에서-txt읽기

를 읽어보면 알겠지만, uiThread의 빠른 작업을 위해 새로운 thread를 생성해서 txt파일을 읽게됩니다. 그런데 새로운 thread가 채 txt파일을 다 읽지 못했는데 바로 onCreate에서 printAll()함수를 실행하면 아직 저장된 arraylist갯수보다 출력하려고 접근하는 index가 커질수도 있어서 exception이 발생하게 됩니다. 그래서 일단 제 소스에서는 btn을 클릭해서 출력하게 만들었습니다만, 제대로 할려면 progressBar를 하나 만들어서 뺑글뺑글 돌리고, thread가 모든 txt파일을 읽은 후에야 출력할 수 있도록 하는게 더 좋은 방법일 것입니다. (실험 소스에서는 단지 6줄의 txt 파일이지만 몇만줄의 txt파일이라면 시간이 꽤 걸릴것이기 때문입니다)

 

 





/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




안드로이드에서는 임의 XML 파일 이외에도 미가공 파일을 사용할 수 있다.
res / 밑에 raw폴더와 asset 폴더에 오디오, 비디오, text 파일을 저장하고 그파일을 읽을 수 있다.

raw 리소스 읽어들이는 형식과 asset 에서 읽어들이는 형식으로 몇 개 짜보았다.
main Keword는 InputStream으로 읽어서, 1byte 씩 조각내서 쓴다.
한글때문에 뻑나면, StreamReader로 해당 charset에 맞춰서 읽는다.
String이나 StringBuffer나 StringBuilder 모두 사용해봤는데, 그닥 차이는 없는듯...

1. asset road resource
1
2
3
4
5
6
7
8
9
10
11
12
private String getStringAssetFile(Activity activity) throws Exception {
    AssetManager as = activity.getAssets();
    InputStream is = as.open("text1.txt");
 
    // InputStreamReader isr = new
    // InputStreamReader(as.open("text1.txt"),"EUC-KR");
 
    String text = convertStreamToString(is);
    is.close();
 
    return text;
}


2. inputStream -> String
1
2
3
4
5
6
7
8
9
10
11
 
private String convertStreamToString(InputStream is) throws IOException {
    ByteArrayOutputStream bs = new ByteArrayOutputStream();
     int i = is.read();
 
    while (i != -1) {
        bs.write(i);
        i = is.read();
    }
    return bs.toString();
}


3. raw road resource -> String-> wirte String Builder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
private String getStringFromRawFile(Activity activity) throws IOException {
 
    Resources r = activity.getResources();
    InputStream is = r.openRawResource(R.raw.text2);
     InputStreamReader r2 = new InputStreamReader(is);
    StringBuilder str = new StringBuilder();
 
    ByteArrayOutputStream bs = new ByteArrayOutputStream();
 
    while (true) {
        int i = r2.read();
 
        if (i == -1)
            break;
        else {
            char c = (char) i;
            str.append(c);
            bs.write(c);
        }
    }
    // StringBuilder sb = sb.append(c);
    // Str    ing myText = is.close();
    return bs.toString();
}


////

반응형