1. 程式人生 > >android檔案操作路徑詳解

android檔案操作路徑詳解

1:內部儲存

     data資料夾就是我們常說的內部儲存,當我們開啟data資料夾之後(沒有root的手機不能開啟該資料夾)   

     data下還有許多資料夾

            一個資料夾是app資料夾,app資料夾裡存放著我們所有安裝的app     的apk檔案

            還有一個資料夾就是data資料夾,這個裡面裝的就是應用的資料資訊

            1.data/data/包名/shared_prefs

            2.data/data/包名/databases

            3.data/data/包名/files

            4.data/data/包名/cache

            3 4路徑獲取的方式:通過當前Context獲取得到  (因為獲取的是當前應用的路徑)

      Log.d(TAG, "initView: getCacheDir=="+getCacheDir());
      Log.d(TAG, "initView: getFilesDir=="+getFilesDir());

2:外部儲存

整個儲存空間分為內部儲存和外部儲存兩部分,內部儲存中又包含RAM和ROM等部分。
一是根目錄下路徑為  /data/data/包名/XX  的檔案。開發中SQLite資料、SharedPreference資料均儲存在這裡,雖說我們可以讀寫操作,
但這部分空間由系統維護。


三是在內建儲存卡中做儲存。在/storage/emulated/0/Android/data包下或與/storage/emulated/0/Android包同級目錄上,建立App包儲存資料,
這部分空間均由開發者維護。區別在於/storage/emulated/0/Android/data包下的資料為私有目錄資料,會隨App解除安裝被清除,
與/storage/emulated/0/Android包同級的資料(如系統目錄DCIM包,DOWNLOWN包和bluetooth包,還有下圖中的baidu包)屬於公有目錄資料,
不會隨App解除安裝被清除,這就會造成資料的解除安裝殘留。



Google官方建議開發者將App的資料儲存在私有目錄即/storage/emulated/0/Android/data包下,這樣解除安裝App時資料會隨之被系統清除,不會造成資料殘留。

data/data/包名/shared_prefs
data/data/包名/databases
data/data/包名/files      context.getFilesDir()
data/data/包名/cache      context.getcacheDir()

內建儲存卡:
共有資料目錄:Environment.getExternalStoragePublicDirectory(String type)  共有目錄不同的就是和apk沒有關係
             不會因為apk的解除安裝而將資料清除掉  所以一般不建議將資料儲存在這個目錄下面。

私有資料目錄:返回的是相對應包名下的資料  會因為apk的解除安裝而資料被清除。
             context.getExternalFilesDir(String type)  /storage/emulated/0/Android/data/files
             context.getEXternalCacheDir()    /storage/emulated/0/Android/data/cache


內部資料:/data/data/包名/XXX

外部私有資料:/storage/emulated/0/Android/data/包名/XXX

外部公有資料:/storage/emulated/0/包名/XXX

清除快取:將外部私有資料下的cache包(/storage/emulated/0/Android/data/包名/cache)清除,將內部資料下的cache包下的內容
(/data/data/包名/cache/XXX)清除 。

清楚資料:將外部私有資料包(/storage/emulated/0/Android/data/包名)清除,將內部資料下的所有內容(/data/data/包名/XXX)清除;

而兩種操作對外部公有資料均無影響。

總結一句話  清除快取就是清除cache資料  清除資料就是清除所有記憶體外存自己報名下的資料  也就是Environment獲取的儲存空間
資料不可以被清除


android中常用的檔案操作相關api:
1:Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)  判斷是否存在外部儲存器
2:String dateDirectory=Environment.getDataDirectory().getAbsolutePath();
   返回的就是date根目錄:/data
3:String downloadcache=Environment.getDownloadCacheDirectory().getAbsolutePath();
   返回的就是cache快取目錄:/cache
4:String externalStorage=Environment.getExternalStorageDirectory().getAbsolutePath();
   返回的就是外部儲存器的目錄:/storage/emulated/0
5:String rootStorage=Environment.getRootDirectory().getAbsolutePath();
   返回的就是system根目錄:/system
6:String externalcachePath=this.getExternalCacheDir().getPath();
   返回/storage/emulated/0/Android/data/com.example.lining.mydemo/cache
7:String filedir=this.getFilesDir().getPath();
   返回/data/data/com.example.lining.mydemo/files
8:String cacheDir=this.getCacheDir().getPath();
   返回/data/data/com.example.lining.mydemo/cache


2:
絕對路徑是指書寫檔案的完整路徑,例如d:\java\Hello.java 但是使用絕對路徑在表示檔案時,受到的限制很大,且不能在不同的作業系統下執行,因為不同作業系統下絕對路徑的表達形式存在不同。
相對路徑是指書寫檔案的部分路徑,例如\test\Hello.java
但是在安卓中,其實多數情況下我們都是使用的絕對路徑。為什麼呢?注意上面說到相對路徑是以當前專案所在路徑為當前路徑,但在安卓中我們是不可能在專案所在路徑目錄下做任何操作的


3:手機內部外部儲存詳解

所有的安卓裝置都有外部儲存和內部儲存,這兩個名稱來源於安卓的早期裝置,那個時候的裝置內部儲存確實是固定的,而外部儲存確實是可以像U盤一樣移動的。但是在後來的裝置中,很多中高階機器都將自己的機身儲存擴充套件到了8G以上,他們將儲存在概念上分成了"內部internal" 和"外部external" 兩部分,但其實都在手機內部。所以不管安卓手機是否有可移動的sdcard,他們總是有外部儲存和內部儲存。最關鍵的是,我們都是通過相同的api來訪問可移動的sdcard或者手機自帶的儲存(外部儲存)。
外部儲存雖然概念上有點複雜,但也很好區分,你把手機連線電腦,能被電腦識別的部分就一定是外部儲存

更為詳細的目錄詳解:
adb shell
  ls  看到的data資料夾就是我們常說的內部儲存      

在data檔案下有app和data兩個關鍵的資料夾:

app:一個資料夾是app資料夾,還有一個資料夾就是data資料夾,app資料夾裡存放著我們所有安裝的app的apk檔案,其實,當我們除錯一個app的時候,可以看到控制檯輸出的內容,有一項是uploading .....就是上傳我們的apk到這個資料夾,上傳成功之後才開始安裝。

data:另一個重要的資料夾就是data檔案夾了,這個資料夾裡邊都是一些包名,開啟這些包名之後我們會看到這樣的一些檔案:


1.data/data/包名/shared_prefs
2.data/data/包名/databases
3.data/data/包名/files
4.data/data/包名/cache
如果開啟過data檔案,應該都知道這些資料夾是幹什麼用的,
我們在使用sharedPreferenced的時候,將資料持久化儲存於本地,其實就是存在這個檔案中的xml檔案裡,
我們App裡邊的資料庫檔案就儲存於databases資料夾中,
還有我們的普通資料儲存在files中,
快取檔案儲存在cache資料夾中,
儲存在這裡的檔案我們都稱之為內部儲存。



4:外部儲存:  外部儲存一般就是我們上面看到的storage資料夾,當然也有可能是mnt資料夾,這個不同廠家有可能不一樣。
  一般來說,在storage資料夾中有一個sdcard資料夾,這個資料夾中的檔案又分為兩類,一類是公有目錄,還有一類是私有目錄,其中的公有目錄有九大類,比如DCIM、DOWNLOAD等這種系統為我們建立的資料夾,私有目錄就是Android這個資料夾,這個資料夾開啟之後裡邊有一個data資料夾,開啟這個data資料夾,裡邊有許多包名組成的資料夾。  


5:操作儲存空間

首先,經過上面的分析,大家已經明白了,什麼是內部儲存,什麼是外部儲存,以及這兩種儲存方式分別儲存在什麼位置,一般來說,我們不會自己去操作內部儲存空間,沒有root許可權的話,我們也沒法操作內部儲存空間,事實上內部儲存主要是由系統來維護的。不過在程式碼中我們是可以訪問到這個資料夾的。由於內部儲存空間有限,在開發中我們一般都是操作外部儲存空間,Google官方建議我們App的資料應該儲存在外部儲存的私有目錄中該App的包名下,這樣當用戶解除安裝掉App之後,相關的資料會一併刪除,如果你直接在/storage/sdcard目錄下建立了一個應用的資料夾,那麼當你刪除應用的時候,這個資料夾就不會被刪除。



1:快取資料到本地的demo

  String fileName="myfile";
        String string= "helloworld8888899999888899988899988999776655fhgyjjkkkkj";
        FileOutputStream fileOutputStream;
                try{
                    Toast.makeText(context,"哈哈哈哈",Toast.LENGTH_SHORT).show();
                    fileOutputStream=openFileOutput(fileName, Context.MODE_PRIVATE);
                    fileOutputStream.write(string.getBytes());
                    fileOutputStream.flush();
                    fileOutputStream.close();
                }catch (Exception e){
                    Log.e("Exception===",e.toString());
                }
            }
        });


 String fileName="myfile";
        String string= "1jjkkkkj";
                File file=new File(context.getFilesDir(),fileName);
                Log.e("file==",file.getPath());
                try {
                    Toast.makeText(context,"哈哈哈哈",Toast.LENGTH_SHORT).show();
                    FileOutputStream fileOutputStream=new FileOutputStream(file);
                    fileOutputStream.write(string.getBytes());
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }


內部儲存的其他一些操作:

A.列出所有的已建立的檔案,這個可能不容易想到,Context居然有這樣的方法。

String[] files = Context.fileList();
for(String file : files) {
Log.e(TAG, "file is "+ file);
}

 

B.刪除檔案,能建立就要能夠刪除,當然也會提供了刪除檔案的介面,它也非常簡單,只需要提供檔名

if(Context.deleteFile(filename)) {
Log.e(TAG, "delete file "+ filename + " sucessfully“);
} else {
Log.e(TAG, "failed to deletefile " + filename);
}

C.建立一個目錄,需要傳入目錄名稱,它返回 一個檔案物件用到操作路徑

File workDir = Context.getDir(dirName, Context.MODE_PRIVATE);
Log.e(TAG, "workdir "+ workDir.getAbsolutePath();





4:外部儲存詳解:
   分為公共檔案和私有檔案
   1:公共檔案:公共檔案Public files:檔案是可以被自由訪問,且檔案的資料對其他應用或者使用者來說都是由意義的,當應用被解除安裝之後,
      其解除安裝前建立的檔案仍然保  留。比如camera應用,生成的照片大家都能訪問,而且camera不在了,照片仍然在。

public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = newFile(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if(!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
returnfile;
}

在上面的程式碼中我們建立獲得了存放picture的目錄,並且新建立一個albumName檔案。

如果你的api 版本低於8,那麼不能使用getExternalStoragePublicDirectory(),而是使用Environment.getExternalStorageDirectory(),他不帶引數,也就不能自己建立一個目錄,只是返回外部儲存的根路徑。








   2:私有檔案:私有檔案Private files:其實由於是外部儲存的原因即是是這種型別的檔案也能被其他程式訪問,只不過一個應用私有的檔案對
      其他應用其實是沒有訪問價值的(惡意程式除外)。外部儲存上,應用私有檔案的價值在於解除安裝之後,這些檔案也會被刪除。類似於內部儲存。
     

public File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = newFile(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if(!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
returnfile;
}



在使用外部儲存之前,你必須要先檢查外部儲存的當前狀態,以判斷是否可用。

boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} elseif(Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else{
// Something else is wrong. It may be one of many other states, but all we need
//  to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}




盒子裡面apk下載路徑:

1:mnt/sdcard/ 隨後就是我們的建立檔案的名稱
   下載圖片的路徑也是在mnt/sdcard/Download/jpg目錄下面   

context獲取相關路徑  一般資料直接放到apk的私有目錄下面  這個解除安裝apk不會導致資料殘留

Environment方式獲取路徑 可以獲取系統的公共目錄  一般不建議這樣做。