Android 文件讀寫


一、分類

文件讀寫作為Android四大數據存儲方式之一,又分為內部存儲和外部存儲兩種:

(1)內部存儲(Internal storage):

  1. 總是可用。
  2. 文件默認情況存儲在/data/data/包名/files,緩存文件存儲在/data/data/包名/cache中,默認情況下只能只能被本APP操作,當然可以在openFileOutput()中指定是否可被其他app讀寫。
  3. 當使用者卸載你的app時,系統會自動從內部存儲中刪除安排app的所有文件。

(2)外部存儲(External storage):

  1.並不是總是可用,因為用戶有可能將SD卡作為USB存儲掛載或者在某些情況下將SD卡從設備上卸下,因此需要使用getExternalStorageState()來查詢外部存儲的狀態,當返回的狀態是MEDIA_MOUNTED時才能讀寫。

  2.保存在外部存儲的文件是world-readable的,所以保存在外部存儲的文件可能被其他應用讀取。

  3.當用戶卸載app時,只用當你調用getExternalFilesDir()來保存文件時系統才會從外部存儲中移除app的文件。

  4.權限:

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

  向SD卡寫入數據權限,隱式授予了讀取權限

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

  當app只需要讀取而非寫入權限的時候更適合使用該權限

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

  在SD卡中創建和刪除文件權限

二、方法介紹

  1)getFilesDir():返回/data/data/包名/files

  2)getCacheDir():返回/data/data/包名/cache,在確定緩存文件不再需要時刪除掉,為app使用的內存量實現一個合理的大小限制,比如1M。如果系統在存儲空間低的時候運行,可能會在沒有警告的時候刪除緩存文件。

  3)FileInputStream openFileInput(String name):打開應用程序文件夾下的nam文件對應的輸入流。

  4)FileOutputStream openFileOutput(String name,int mode):打開應用程序文件夾下的nam文件對應的輸出流(若文件不存在則創建),第二個參數指定打開文件的模式:

    MODE_PRIVATE:該文件只能被當前程序讀寫

    MODE_APPEND:已追加方式打開該文件

    MODE_WORLD_READABLE:該文件可被其他程序讀取

    MODE_WORLD_WRITEABLE:該文件可被其他程序讀寫

  5)getDir(String name,int mode):在應用程序的數據文件夾下獲取或創建app_name對應的子目錄

    第二個參數:     

    MODE_PRIVATE:默認模式,該文件只能被當前程序訪問

    MODE_WORLD_READABLE:該文件可被其他程序訪問(在API17被棄用)

    MODE_WORLD_WRITEABLE:該文件可被其他程序讀寫(在API17被棄用)

  6)String[] fileList():返回應用程序的數據文件夾下的全部文件名

  7)deleteFile(String name):刪除應用程序的數據文件夾下指定文件

  8)Environment.getExternalStorageState():判斷手機是否插入SD卡,當返回MEDIA_MOUNTED時才能對其進行讀寫

  9)getExternalStorageDirectory():返回SD卡的根目錄  /storage/emulated/0

  10)getExternalStoragePublicDirectory(String type):在SD卡的根目錄創建一個由type指定的特定類型的文件夾

  例如:/storage/emulated/0/Pictures

  11)getExternalFilesDir(String type):在SD卡中對應應用的數據文件夾中創建一個由type指定的特定類型的文件夾

  例如:storage/emulated/0/Android/data/應用包名/files/Pictures

  type可選項:

    DIRECTORY_MUSIC 標准音樂目錄,

    DIRECTORY_PODCASTS ,

    DIRECTORY_RINGTONES 鈴聲

    DIRECTORY_ALARMS 警報音

    DIRECTORY_NOTIFICATIONS 通知音,

    DIRECTORY_PICTURES 圖片

    DIRECTORY_MOVIES 電影,

      DIRECTORY_DOWNLOADS 下載

    DIRECTORY_DCIM 由camera拍攝的照片和視頻存放目錄

  TIPS:(1)需要注意的是getExternalStoragePublicDirectory()與getExternalFilesDir()的區別在於前者所創建的文件不會在用戶卸載被系統刪除,而后者在SD卡創建的應用程序數據文件會被系統刪除。

     (2)當用戶卸載APP的時候系統會刪除所有在內部存儲中對應APP的文件以及由getExternalFilesDir()調用創建的文件。

三、代碼示例

內部存儲:

import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    final String FILE_NAME="test.txt";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button read= (Button) findViewById(R.id.read);
        final Button write= (Button) findViewById(R.id.write);
        final EditText editText= (EditText) findViewById(R.id.edit_area);
        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                write(editText.getText().toString());
                editText.setText("");
            }
        });
        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                editText.setText(read());
            }
        });
        findViewById(R.id.delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                delete(FILE_NAME,MainActivity.this);
            }
        });
    }
    private String read(){
        try {
            FileInputStream fis=openFileInput(FILE_NAME);
            byte[] buff=new byte[1024];
            int hasRead=0;
            StringBuffer sb=new StringBuffer();
            while ((hasRead=fis.read(buff))>0){
                sb.append(new String(buff,0,hasRead));
            }
            fis.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private void delete(String name,Context context){
        context.deleteFile(name);
    }
    private void write(String content){
        try {
            FileOutputStream fos=openFileOutput(FILE_NAME,MODE_PRIVATE);
            try {
                fos.write(content.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText
        android:id="@+id/edit_area"
        android:lines="5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/read"
        android:layout_below="@id/edit_area"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="讀入"/>
    <Button
        android:id="@+id/write"
        android:layout_toRightOf="@id/read"
        android:layout_below="@id/edit_area"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="寫入"/>
    <Button
        android:id="@+id/delete"
        android:layout_below="@id/edit_area"
        android:text="刪除"
        android:layout_toRightOf="@id/write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

外部存儲:

package com.example.administrator.externalfile;

import android.content.Context;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;

public class MainActivity extends AppCompatActivity {

    private String TAG="ENTERNAL";
    private String FILE_NAME="/test.txt";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "ExternalStoragePublicDir=" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
        Log.d(TAG, "ExternalFilesDir=" + MainActivity.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES));
        Log.d(TAG,"ExternalStorageDir="+Environment.getExternalStorageDirectory());
        final EditText editText= (EditText) findViewById(R.id.edit_area);
        Button read= (Button) findViewById(R.id.read);
        final Button write= (Button) findViewById(R.id.write);
        read.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                editText.setText(read());
            }
        });
        write.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                write(editText.getText().toString());
                editText.setText("");
            }
        });
    }
     public boolean isExternalStorageWritable(){
         String state= Environment.getExternalStorageState();
         if (Environment.MEDIA_MOUNTED.equals(state)){
             return true;
         }
         return false;
     }
    public boolean isExternalStorageReadable(){
        String state=Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)||Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)){
            return true;
        }
        return false;
    }

    /**
     * 獲取外部公用存儲路徑
     * @param albumName
     * @return
     */
    public File getAlbumStorageDir(String albumName){
        File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),albumName);
        if (!file.mkdirs()){
            Log.d(TAG,"Directory not create");
        }
        return file;
    }

    /**
     * 獲取私有外部存儲目錄
     * @param context
     * @param albumName
     * @return
     */
    public File getAlbumStorageDir(Context context,String albumName){
        File file=new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),albumName);
        if (!file.mkdirs()){
            Log.d(TAG,"Directory not create");
        }
        return file;
    }
    private String read(){
        if (isExternalStorageWritable()){
//            File sdCard=Environment.getExternalStorageDirectory();
            File sdCard=getAlbumStorageDir(MainActivity.this,"test");
            try {
                FileInputStream fis=new FileInputStream(sdCard.getCanonicalPath()+FILE_NAME);
                StringBuilder sb=new StringBuilder("");
                byte[] buff=new byte[1024];
                int hasRead=0;
                while ((hasRead=fis.read(buff))!=-1){
                    sb.append(new String(buff,0,hasRead));
                }
                return sb.toString();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private void write(String content){
        if (isExternalStorageWritable()){
//            File sdCard=Environment.getExternalStorageDirectory();
            File sdCard=getAlbumStorageDir(MainActivity.this,"test");
            try {
                File targetFile=new File(sdCard.getCanonicalPath()+FILE_NAME);
                RandomAccessFile raf=new RandomAccessFile(targetFile,"rw");
                raf.seek(targetFile.length());
                raf.write(content.getBytes());
                raf.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <EditText
        android:id="@+id/edit_area"
        android:lines="5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/read"
        android:layout_below="@id/edit_area"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="讀入"/>
    <Button
        android:id="@+id/write"
        android:layout_toRightOf="@id/read"
        android:layout_below="@id/edit_area"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="寫入"/>
    <Button
        android:id="@+id/delete"
        android:layout_below="@id/edit_area"
        android:text="刪除"
        android:layout_toRightOf="@id/write"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

 

 

參考自:

  http://developer.android.com/training/basics/data-storage/files.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM