수색…


소개

Android에서 파일을 읽고 쓰는 일은 표준 Java에서 파일을 읽고 쓰는 것과 다릅니다. 같은 java.io 패키지를 사용할 수 있습니다. 그러나 일반적으로 사용 권한을 쓰고 MTP를 처리 할 수있는 폴더와 관련된 몇 가지 특정 항목이 있습니다.

비고

Android는 여기에 설명 된대로 여러 애플리케이션간에 파일을 공유 할 수있는 방법을 제공합니다. 파일을 만들고 사용하는 앱이 하나 뿐인 경우에는 필요하지 않습니다.

Android는 공유 및 개인 환경 설정, 저장된 번들 및 기본 제공 데이터베이스와 같은 대체 저장 옵션을 제공합니다. 어떤 경우에는 일반 파일을 사용하는 것보다 더 나은 선택입니다.

Android 활동에는 Java 표준 파일 IO 메소드 대신 사용할 수있는 특정 메소드가 거의 없습니다. 예를 들어, File.delete() 대신 Context.deleteFile() 호출 할 수 있으며, File.listFiles() 재귀 적으로 적용하는 대신 Context.fileList() 를 호출하여 모든 특정 응용 프로그램의 파일 목록을 얻을 수 있습니다 암호. 그러나 표준 java.io 패키지 이외에 추가 기능을 제공하지는 않습니다.

작업 폴더 얻기

액티비티에서 getFilesDir() 메서드를 호출하여 작업 폴더를 가져올 수 있습니다 (Activity는 컨텍스트에서 상속 한 응용 프로그램의 중심 클래스입니다. 여기를 참조 하십시오 ). 독서는 다르지 않습니다. 응용 프로그램에서만이 폴더에 액세스 할 수 있습니다.

활동에는 다음과 같은 코드가 포함될 수 있습니다.

  File myFolder = getFilesDir();
  File myFile = new File(myFolder, "myData.bin");

바이트의 raw 배열의 기입

  File myFile = new File(getFilesDir(), "myData.bin");
  FileOutputStream out = new FileOutputStream(myFile);

  // Write four bytes one two three four:
  out.write(new byte [] { 1, 2, 3, 4}
  out.close()

이 코드와 관련된 Android는 없습니다. 작은 값을 많이 쓰는 경우 BufferedOutputStream 을 사용하여 장치 내부 SSD의 마모를 줄이십시오.

객체 직렬화

오래된 좋은 Java 객체 직렬화는 Android에서 사용할 수 있습니다. 다음과 같이 Serializable 클래스를 정의 할 수 있습니다.

  class Cirle implements Serializable {
    final int radius;
    final String name;

    Circle(int radius, int name) {
      this.radius = radius;
      this.name = name;
    }
  }

다음에 ObjectOutputStream에 기입 해주세요.

  File myFile = new File(getFilesDir(), "myObjects.bin");
  FileOutputStream out = new FileOutputStream(myFile);
  ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(out));

  oout.writeObject(new Circle(10, "One"));
  oout.writeObject(new Circle(12, "Two"));
  
  oout.close()

Java 객체 직렬화는이 자습서의 범위와 때로는 의견을 바탕으로하지 않고서는 무엇을하고 싶은지에 따라 완벽하거나 나쁜 선택 일 수 있습니다. 사용하기로 결정한 경우 먼저 버전 관리 에 대해 읽어보십시오.

외부 저장소 (SD 카드)에 쓰기

또한 많은 Android 기기에있는 메모리 카드 (SD 카드)에서 읽고 쓸 수 있습니다. 이 위치에있는 파일은 USB 케이블을 통해 장치를 PC에 연결하고 MTP 프로토콜을 활성화 한 후 사용자가 직접 다른 프로그램에서 액세스 할 수 있습니다.

SD 카드 위치를 찾는 것이 다소 문제가됩니다. Environment 클래스에는 SD 카드 안에 있어야하는 "외부 디렉토리"를 가져 오는 정적 메서드가 포함되어 있으며 SD 카드가 있고 쓰기 가능한 경우 정보도 들어 있습니다. 이 질문 에는 올바른 위치를 찾는 방법에 대한 귀중한 답 포함되어 있습니다.

외부 저장소에 액세스하려면 권한이 필요합니다. Android 매니페스트 :

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

이전 버전의 Android 용 권한을 사용하는 경우 이러한 권한을 매니페스트에 넣으면 충분합니다 (사용자는 설치 중에 승인해야 함). 그러나 안드로이드 6.0에서 시작하면 안드로이드는 처음 액세스 할 때 사용자에게 승인을 요청하며,이 새로운 접근 방법을 지원해야합니다. 그렇지 않으면 매니페스트에 관계없이 액세스가 거부됩니다.

안드로이드 6.0에서 먼저 권한을 확인한 다음 승인되지 않은 경우 요청해야합니다. 코드 예제는 이 SO 질문 에서 찾을 수 있습니다.

"보이지 않는 MTP 파일"문제 해결.

MTP 프로토콜을 사용하여 USB 케이블을 통해 데스크톱으로 내보낼 파일을 만드는 경우 새로 생성 된 파일이 연결된 데스크톱 PC에서 실행중인 파일 탐색기에 즉시 표시되지 않을 수 있습니다. 새 파일을 표시하려면 MediaScannerConnection 을 호출해야합니다.

File file = new File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_DOCUMENTS), "theDocument.txt");
FileOutputStream out = new FileOutputStream(file)

... (write the document)

out.close()
MediaScannerConnection.scanFile(this, new String[] {file.getPath()}, null, null);
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
            Uri.fromFile(file)));

이 MediaScannerConnection 호출 코드는 디렉토리가 아닌 파일에서만 작동합니다. 문제는 이 Android 버그 보고서에 설명되어 있습니다. 이 버전은 향후 일부 버전이나 일부 장치에서 수정 될 수 있습니다.

대용량 파일 작업

작은 파일은 초 단위로 처리되며 필요한 부분의 코드 대신 해당 파일을 읽고 쓸 수 있습니다. 그러나 파일이 커지거나 처리 속도가 느린 경우 안드로이드에서 AsyncTask를 사용하여 백그라운드에서 파일 작업을해야 할 수도 있습니다.

    class FileOperation extends AsyncTask<String, Void, File> {

        @Override
        protected File doInBackground(String... params) {
          try {
            File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOCUMENTS), "bigAndComplexDocument.odf");
            FileOutputStream out = new FileOutputStream(file)

           ... (write the document)

            out.close()
            return file;
            } catch (IOException ex) {
               Log.e("Unable to write", ex);
               return null;
              }
        }

        @Override
        protected void onPostExecute(File result) {
          // This is called when we finish 
        }

        @Override
        protected void onPreExecute() {
           // This is called before we begin
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            // Unlikely required for this example
        }
    }
}

그리고

new FileOperation().execute("Some parameters");    

이 SO 질문 에는 AsyncTask를 작성하고 호출하는 방법에 대한 완전한 예가 들어 있습니다. 또한 IOExceptions 및 기타 오류를 처리하는 방법 에 대한 오류 처리에 대한 질문을 참조하십시오.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow