Android Studio——android中的檔案操作詳解以及內部儲存和外部儲存
原文連結:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0923/1557.html
其實安卓檔案的操作和java在pc環境下的操作並無二致,之所以需要單獨講解是因為安卓系統提供了不同於pc的訪問檔案系統根路徑的api,同時對一個應用的私有檔案做了統一的管理。根據我的經驗,初學者在這部分感到很容易混淆內部儲存和外部儲存兩個概念。
相對路徑和絕對路徑
在java中,關於相對路徑和絕對路徑是這樣解釋的,如果你很熟悉這部分以下灰色文字可以跳過:
絕對路徑是指書寫檔案的完整路徑,例如d:\java\Hello.java,該路徑中包含檔案的完整路徑d:\java以及檔案的全名Hello.java。使用該路徑可以唯一的找到一個檔案,不會產生歧義。但是使用絕對路徑在表示檔案時,受到的限制很大,且不能在不同的作業系統下執行,因為不同作業系統下絕對路徑的表達形式存在不同。
相對路徑是指書寫檔案的部分路徑,例如\test\Hello.java,該路徑中只包含檔案的部分路徑\test和檔案的全名Hello.java,部分路徑是指當前路徑下的子路徑,例如當前程式在d:\abc下執行,則該檔案的完整路徑就是d:\abc\test。使用這種形式,可以更加通用的代表檔案的位置,使得檔案路徑產生一定的靈活性。
在Eclipse專案中執行程式時,當前路徑是專案的根目錄,例如工作空間儲存在d:\javaproject,當前專案名稱是Test,則當前路徑是:d:\javaproject\Test。在控制檯下面執行程式時,當前路徑是class檔案所在的目錄,如果class檔案包含包名,則以該class檔案最頂層的包名作為當前路徑。
這是java在多數作業系統中這樣操作,很顯然是要我們儘可能的使用相對路徑,但是在安卓中,其實多數情況下我們都是使用的絕對路徑。為什麼呢?注意上面說到相對路徑是以當前專案所在路徑為當前路徑,但在安卓中我們是不可能在專案所在路徑目錄下做任何操作的,因為普通java中我們的專案創建於伺服器(pc也算是伺服器),運行於伺服器,我們當然能在伺服器操作自己的檔案目錄。但是安卓開發中,我們的專案一般是創建於自己工作的電腦,而運行於手機,既然apk已經運行於手機了,那專案就已經部署到手機上了,應該以apk在手機上的位置來確定相對路徑,但我們好像們沒有辦法操作這個路徑的,因為apk是在system目錄下,就算可以操作,在這個目錄下存取檔案也是沒有意義的,比如我寫一個相簿程式,圖片肯定是放在外部儲存中,而如果我要儲存一個應用的一些設定資料,我是放在內部儲存的data目錄下,因此其實在安卓檔案管理中,我們都是在操作絕對路徑。
File類
操作一個檔案(讀寫,建立檔案或者目錄)是通過File類來完成的,這個操作和java中完全一致。
外部儲存external storage和內部儲存internal storage
1.內部儲存:
注意內部儲存不是記憶體。內部儲存位於系統中很特殊的一個位置,如果你想將檔案儲存於內部儲存中,那麼檔案預設只能被你的應用訪問到,且一個應用所建立的所有檔案都在和應用包名相同的目錄下。也就是說應用創建於內部儲存的檔案,與這個應用是關聯起來的。當一個應用解除安裝之後,內部儲存中的這些檔案也被刪除。從技術上來講如果你在建立內部儲存檔案的時候將檔案屬性設定成可讀,其他app能夠訪問自己應用的資料,前提是他知道你這個應用的包名,如果一個檔案的屬性是私有(private),那麼即使知道包名其他應用也無法訪問。內部儲存空間十分有限,因而顯得可貴,另外,它也是系統本身和系統應用程式主要的資料儲存所在地,一旦內部儲存空間耗盡,手機也就無法使用了。所以對於內部儲存空間,我們要儘量避免使用。Shared Preferences和SQLite資料庫都是儲存在內部儲存空間上的。內部儲存一般用Context來獲取和操作。
getFilesDir()獲取你app的內部儲存空間,相當於你的應用在內部儲存上的根目錄。
如果是要建立一個檔案,如下
1 |
File
file = newFile(context.getFilesDir(), filename);
|
安卓還為我們提供了一個簡便方法 來讀寫應用在內部儲存空間上的檔案,下面是一個向檔案中寫入文字的例子:
1 2 3 4 5 6 7 8 9 10 |
String
filename = "myfile" ;
String
string = "Hello
world!" ;
FileOutputStream
outputStream;
try {
outputStream
= openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
}
catch (Exception
e) {
e.printStackTrace();
}
|
內部儲存的其他一些操作:
A.列出所有的已建立的檔案,這個可能不容易想到,Context
居然有這樣的方法。
1 2 3 4 |
String[]
files = Context.fileList();
for (String
file : files) {
Log.e(TAG,
"file
is " +
file);
}
|
B.刪除檔案,能建立就要能夠刪除,當然也會提供了刪除檔案的介面,它也非常簡單,只需要提供檔名
1 2 3 4 5 |
if (Context.deleteFile(filename))
{
Log.e(TAG,
"delete
file " +
filename + "
sucessfully“);
}
else {
Log.e(TAG,
" failed
to deletefile " + filename);
}
|