首先內部存儲路徑為/data/data/youPackageName/,下面講解的各路徑都是基于你自己的應用的內部存儲路徑下。所有內部存儲中保存的文件在用戶卸載應用的時候會被刪除。
一、 files
1. Context.getFilesDir(),該方法返回/data/data/youPackageName/files的File對象。
2. Context.openFileInput()與Context.openFileOutput(),只能讀取和寫入files下的文件,返回的是FileInputStream和FileOutputStream對象。
3. Context.fileList(),返回files下所有的文件名,返回的是String[]對象。
4. Context.deleteFile(String),刪除files下指定名稱的文件。
二、cache
1. Context.getCacheDir(),該方法返回/data/data/youPackageName/cache的File對象。
三、custom dir
getDir(String name, int mode),返回/data/data/youPackageName/下的指定名稱的文件夾File對象,如果該文件夾不存在則用指定名稱創建一個新的文件夾。
有了數據存儲 API,您可以使用內部存儲器存儲數據。信息可以是私有的,您可以有選擇地讓其他應用程序對之具有讀或寫的訪問權限。本節介紹這個存儲私有數據的 API,它使用 android.content.Context.openFileInput、openFileOutput 和 getCacheDir() 來高速緩存數據,而不是永久地存儲。
清單 20 中的代碼片段展示了如何從內部私有存儲器讀取數據。使得存儲器為私有的方法是對 openFileOutput() 使用MODE_PRIVATE。
清單 20. 從本地私有存儲器讀取數據
/**
* Writes content to internal storage making the content private to
* the application. The method can be easily changed to take the MODE
* as argument and let the caller dictate the visibility:
* MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc.
*
* @param filename - the name of the file to create
* @param content - the content to write
*/
public void writeInternalStoragePrivate(
String filename, byte[] content) {
try {
//MODE_PRIVATE creates/replaces a file and makes
// it private to your application. Other modes:
// MODE_WORLD_WRITEABLE
// MODE_WORLD_READABLE
// MODE_APPEND
FileOutputStream fos =
openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(content);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
清單 21 中的代碼片段展示了如何從內部私有存儲器讀取數據;注意 openFileInput() 的使用。
清單 21. 從內部私有存儲器讀取數據
/**
* Reads a file from internal storage
* @param filename the file to read from
* @return the file content
*/
public byte[] readInternalStoragePrivate(String filename) {
int len = 1024;
byte[] buffer = new byte[len];
try {
FileInputStream fis = openFileInput(filename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nrb = fis.read(buffer, 0, len); // read up to len bytes
while (nrb != -1) {
baos.write(buffer, 0, nrb);
nrb = fis.read(buffer, 0, len);
}
buffer = baos.toByteArray();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return buffer;
}
清單 22 展示了如何從內部私有存儲器刪除數據。
清單 22. 從本地私有存儲器刪除數據
/**
* Delete internal private file
* @param filename - the filename to delete
*/
public void deleteInternalStoragePrivate(String filename) {
File file = getFileStreamPath(filename);
if (file != null) {
file.delete();
}
}
現在可以來看為公共數據使用外部存儲器了。
回頁首
為公共數據使用設備的外部存儲器
有了數據存儲 API,您可以使用外部存儲器存儲數據。信息可以是私有的,您可以有選擇地讓其他應用程序對之具有讀或寫的訪問權限。本節您將對此 API 進行編程,以便使用包括getExternalStorageState()、getExternalFilesDir()、getExternalStorageDirectory() 和getExternalStoragePublicDirectory() 在內的很多 API 來存儲公共數據。您為公共數據使用下面的路徑:/Android/data/<package_name>/files/。
在使用外部存儲器之前,必須看看它是否可用,是否可寫。下面兩個代碼片段展示了測試這些條件的幫助器方法。清單 23 測試外部存儲器是否可用。
清單 23. 測試外部存儲器是否可用
/**
* Helper Method to Test if external Storage is Available
*/
public boolean isExternalStorageAvailable() {
boolean state = false;
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
state = true;
}
return state;
}
清單 24 測試外部存儲器是否只可讀。
清單 24. 測試外部存儲器是否只可讀
/**
* Helper Method to Test if external Storage is read only
*/
public boolean isExternalStorageReadOnly() {
boolean state = false;
String extStorageState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
state = true;
}
return state;
}
清單 25 展示了如何寫到外部存儲器,以存儲公共數據。
清單 25. 寫到外部內存
/**
* Write to external public directory
* @param filename - the filename to write to
* @param content - the content to write
*/
public void writeToExternalStoragePublic(String filename, byte[] content) {
// API Level 7 or lower, use getExternalStorageDirectory()
// to open a File that represents the root of the external
// storage, but writing to root is not recommended, and instead
// application should write to application-specific directory, as shown below.
String packageName = this.getPackageName();
String path = "/Android/data/" + packageName + "/files/";
if (isExternalStorageAvailable() &&
!isExternalStorageReadOnly()) {
try {
File file = new File(path, filename);
file.mkdirs();
FileOutputStream fos = new FileOutputStream(file);
fos.write(content);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
清單 26 展示了如何從外部存儲器讀取數據。
清單 26. 從外部內存讀取數據
/**
* Reads a file from internal storage
* @param filename - the filename to read from
* @return the file contents
*/
public byte[] readExternallStoragePublic(String filename) {
int len = 1024;
byte[] buffer = new byte[len];
String packageName = this.getPackageName();
String path = "/Android/data/" + packageName + "/files/";
if (!isExternalStorageReadOnly()) {
try {
File file = new File(path, filename);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nrb = fis.read(buffer, 0, len); //read up to len bytes
while (nrb != -1) {
baos.write(buffer, 0, nrb);
nrb = fis.read(buffer, 0, len);
}
buffer = baos.toByteArray();
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return buffer;
}
清單 27 中的代碼片段展示了如何從外部內存刪除文件。
清單 27. 從外部內存刪除文件
/**
* Delete external public file
* @param filename - the filename to write to
*/
void deleteExternalStoragePublicFile(String filename) {
String packageName = this.getPackageName();
String path = "/Android/data/" + packageName + "/files/"+filename;
File file = new File(path, filename);
if (file != null) {
file.delete();
}
}
處理外部存儲器需要特殊的權限 WRITE_EXTERNAL_STORAGE,它通過 AndroidManifest.xml 請求得到(參見 清單 28)。
清單 28. WRITE_EXTERNAL_STORAGE
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
外部存儲 API 通過根據文件類型(比如 Pictures、Ringtones)將文件存儲在預先確定的目錄中,允許您公共地存儲文件。本文沒有介紹這種方法,但是您應該熟悉它。此外,記住外部存儲器中的文件任何時候都可能消失。
回頁首
相關的方法
如果您具有不需要長期永久保存的臨時文件,那么可以將這些文件存儲在高速緩存中。高速緩存是一種特殊的內存,可以用于存儲中小型數據(少于兆字節),但是您一定要知道,取決于有多少內存可用,高速緩存的內容任何時候都可能被清除。
清單 29 展示了一個幫助器方法,它返回到內部內存中高速緩存的路徑。
清單 29. 檢索到內部內存高速緩存的路徑
/**
* Helper method to retrieve the absolute path to the application
* specific internal cache directory on the file system. These files
* will be ones that get deleted when the application is uninstalled or when
* the device runs low on storage. There is no guarantee when these
* files will be deleted.
*
* Note: This uses a Level 8+ API.
*
* @return the absolute path to the application specific cache
* directory
*/
public String getInternalCacheDirectory() {
String cacheDirPath = null;
File cacheDir = getCacheDir();
if (cacheDir != null) {
cacheDirPath = cacheDir.getPath();
}
return cacheDirPath;
}
清單 30 展示了一個幫助器方法,它返回到外部內存中高速緩存的路徑。
清單 30. 檢索到外部內存高速緩存的路徑
/**
* Helper method to retrieve the absolute path to the application
* specific external cache directory on the file system. These files
* will be ones that get deleted when the application is uninstalled or when
* the device runs low on storage. There is no guarantee when these
* files will be deleted.
*
* Note: This uses a Level 8+ API.
*
* @return the absolute path to the application specific cache
* directory
*/
public String getExternalCacheDirectory() {
String extCacheDirPath = null;
File cacheDir = getExternalCacheDir();
if (cacheDir != null) {
extCacheDirPath = cacheDir.getPath();
}
return extCacheDirPath;
}
通過使用示例應用程序,您現在應該很好地理解了如何為公共數據使用設備的外部存儲器。