(안드로이드) 파일 저장하기

안드로이드는 다르 플랫폼의 디스크 기반 파일시스템과 유사한 파일 시스템을 사용한다.

File객체는 건너띄는 것 없이 처음부터 끝까지 순서대로 많은 양의 데이터를 읽고 쓰는데 적합하다. 예를들어, 이미지 파일이나 네트워크를 통해 변경되어지는 것들을 저장흐넨ㄷ 좋다.

내부 또는 외부 저장장치 선택

모든 안드로이드 단말기들은 두개의 파일 저장 영역을 가지고 있다. "Internal" 과 "External" 저장장치 이 저장소의 이름들은 안드로이드 이전부터 만들어져 있던 것들입니다. 대부분의 단말기들은 내장되어 있는 비휘발성 메모리(내부 메모리)가 제공되어 있으며, 추가적으로 SD card(External Storage)와 같은 제거할 수 있는(removable) 저장장치를 가지고 있다. 

내부 저장장치(Interanal Storage)

  • 이 장치는 항상 사용할 수 있습니다.
  • 이곳에 저장된 파일을 기본적으로는 오직 여러분의 앱에 의해서만 접속할 수 있다.
  • 사용자가 여러분의 앱을 언인스톨할 때, 시스템은 내부저장소로부터 앱의 파일들을 모두 제거한다.
  • 내부 저장소는 사용자든 다른 앱들이든 여러분의 파일에 접속할 수 없도록 하고 싶을때 사용하기 좋은 곳이다.

외부 저장장치(Interanal Storage)

  • 이 장치는 항상 사용할 수는 없다. 왜냐하면 사용자가 USB저장장치처럼 외부저장소를마운트(mount) 할 수도있고, 어떤 경우에는 단말기에서 제거할 수도 있기 때문이다.
  • 이 장치는 기본적으로 world-readable이다. 그래서 저장된 파일은 여러분의 제어밖에서(동의없이) 읽어질 수도 있다.
  • 사용자가 여러분의 앱을 언인스톨할 때, 시스템은 여러분이 getExternalFilesDir()로 만든 디렉토리에 파일을 저장했을때만 자동으로 제거된다.
  • 외부 저장소는 파일의 접속제한이 필요하지 않으며, 다른 앱들이나 사용자가 컴퓨터를 사용하여 접속하도록 공유하고 싶을 때 사용하기 좋은 곳이다.



TIP: 기본적으로 앱들은 내부저장소에 인스톨되지만, 메니페스트 안에 android:installLocation 속성을 통해 저장위치를 지정할 수 있다. 그래서 여러분의 앱이 외부저장장치에 인스톨되도록 할 수 있다. 사용자는 내부 저장소보다 큰 외부 저장소를 가지고 있으며 


<내부 저장장치에 파일 저장하기(Save a File on Internal Storage)>


내부 저장소에 파일을 저장할 때, 아래의 두개 메소드 중 하나를 호출함으로써 파일을 저장할 알맞은 디렉토리를 가지고 있는 File인스턴스를 얻을 수 있습니다.


*getFileDir()
  여러분의 앱이 저장된 내부 저장소의 디렉토리(internal directory)를 나타내고 있는 File인스턴스(instance)를 리턴한다.

*getCacheDir()
앱의 임시 캐시(cache)파일을 저장하고 있는 내부 저장소의 디렉토리를 나타내고 있는 File인스턴스를 리턴합니다. 파일이 더 이상 필요하지 않으면 각 파일을 삭제해야 하며 1MB와 같이, 주어진 시간에 사용되는 메모리의 총량에 대한 합리적인 크기제한을 구현합니다. 
만약 시스템의 저장공간이 부족해 지기 시작하면, 어떠한 경고도 없이 여러분의 캐시(cache)파일을 제거 할 수도 있습니다.

이들 디렉토리중 하나에 새로운 파일을 생성하기 위해서는, File() 생성자 함수를 호출하면서 파라미터로 여러분의 내부 저장 디렉토리를 지정하는 위의 메소드중 하나를 사용해서 File객체를 전달합니다. 

예)
File file=new File(context.getFilesDir(), filename);

위를 대체해서, 여러분은 앱의 내부 저장 디렉토리의 파일에 쓰기(저장)을 하도록 하는 
FileOutputStream객체를 openFileOutput()을 호출하여 사용할 수도 있습니다. 아래는파일에 몇가지 텍스트를 쓰는 방법의 예제이다.

예)
String string="Hello world";
FileOutputStream outputStream;

try{
    outputStream=openFileOutput("파일이름",Context.MODE_PRIVATE);
    outputStream.write(string.getBytes());
    outputStream.close();
}catch(Exception e){
  e.printStackTrace();
}


또한, 만약 일부의 파일들을 캐시메모리에 저장할 필요가 있다면, createTempFile() 로 대신하여 사용해야 한다. 예를들어, 아래의 메소드는 URL로부터 파일이름을 추출하여, 앱의 내부 캐시 디렉토리안에 추출된 이름으로 파일을 만든다.

pulic File getTempFile(Cotext context, String url){
    File file;
   try{
        String fileName=Uri.parse(url).getLastPathSegment();
         file=File.createTempFile("파일이름",null,context.getCacheDir());
   }catch(IOException e){
        //Error while creating file
  }
  return file;
}


NOTE: 앱이 저장되는 내부 저장 디렉토리는 안드로이드 파일 시스템의 특정 지역안에 앱의 패키지 이름으로 지정된다. 기술적으로, 다른 앱은 여러분이 읽을 수 있도록 설정하기만 했다면 여러분 앱의 내부 저장 파일을 읽을 수 있다. 어쩃든, 여러분의 앱의 패키지이름과 파일이름을 알아야만 한다. 다른 앱들은 여러분이 명시적으로 여러분의 파일을 읽고 쓸 수 있도록 설정하지 않은 상태에서 여러분의 내부 디렉토리를 탐색하거나 읽고 쓸수 없습니다.
그래서 내부 저장소에 있는 여러분의 파일에 대해 MODE_PRIVATE로 하기만한다면, 다른 앱들은 절대로 여러분의 파일에 접속할 수 없습니다.




Tip : 기본적으로 앱들은 내부 저장소(Internal Storage)에 인스톨(install)되지만, 메니페스트 안에 android:installLocation 속성을 통해 저장위치를 지정할 수 있습니다. 그래서 여러분의 앱이 외부 저장장치(External Storage)에 인스톨(install)되도록 할 수 있습니다. 사용자는 내부 저장소(Internal Storage) 보다 큰 외부 저장소(External Storage)를 가지고 있으며 APK(Android Package)의 용량이 매우 클 때 이 옵션의 진가를 느끼게 됩니다.





댓글

이 블로그의 인기 게시물

(네트워크)폴링방식 vs 롱 폴링방식

(ElasticSearch) 결과에서 순서 정렬

(18장) WebSocekt과 STOMP를 사용하여 메시징하기