Android
안드로이드와 FileIO
수색…
소개
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 및 기타 오류를 처리하는 방법 에 대한 오류 처리에 대한 질문을 참조하십시오.