Android之File操作許可權
一、File類
Java提供了一套完整的I/O流體系,包括FileInputStream、FileOutputStream等,Android中同樣也有類似方法來訪問手機儲存器上的檔案。
openFileOutput(String name)和openFileInput(String name, int mode)分別返回FileOutputStream類和FileInputStream類。由於操作簡單,以下程式碼來自網際網路:
private String read() { try { // 開啟檔案輸入流 FileInputStream fis = openFileInput(FILE_NAME); byte[] buff = new byte[1024]; int hasRead = 0; StringBuilder sb = new StringBuilder(""); // 讀取檔案內容 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 write(String content) { try { // 以追加模式開啟檔案輸出流 FileOutputStream fos = openFileOutput(FILE_NAME, MODE_APPEND); // 將FileOutputStream包裝成PrintStream PrintStream ps = new PrintStream(fos); // 輸出檔案內容 ps.println(content); // 關閉檔案輸出流 ps.close(); } catch (Exception e) { e.printStackTrace(); } }
二、讀寫SD卡檔案
上述方法中,需要注意的有一點,FileInputStream fis = openFileInput(FILE_NAME);這句話中,FILE_NAME為檔名,其不包含該檔案的路徑,那麼程式預設開啟的都是應用程式的資料資料夾裡的檔案,很多時候,我們需要讀寫的是SD卡上的檔案。android中,SD卡的預設路徑是“/mnt/sdcard/”。
讀寫SD卡的步驟如下:
(1)呼叫Environment的getExternalStorageState()方法判斷是否插入SD卡,以及是否具有SD卡讀取許可權。
(2)呼叫Environment的getExternalStorageDirectory()方法獲取外部儲存器,也就是SD卡的目錄。
(3)呼叫FileInputStream、FileOutputStream、FileReader或FilderWriter讀寫SD卡的檔案。
File file = new File("/mnt/sdcard/");
if(file.exists()) {
File[] currentFiles = file.listFile();
// WHAT YOU WANT TO DO
}
還有一點不能忘記,那就是讀寫SD的許可權:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
(注意其在AndroidManifest.xml中的位置)
三、修改檔案許可權
終於說到重點啦。
用過Linux系統的童鞋一定對Linux系統的許可權控制比較瞭解,Android的核心就是Linux,因此,Android系統中檔案的許可權也是一個很有趣的東西。
首先,要說明的就是通過adb shell來檢視系統的檔案(在Windows系統中無法看到Android系統的檔案組織結構?)
這裡說明兩個目錄:/data和/mnt。/data是我們的應用程式儲存資料地方,比如在Eclipse中的File Exploer中看到的/data/data/PACKAGE_NAME/FILE_FOLDER(該路徑為其絕對路徑)。
在該shell中,由於其核心是Linux的,所以,把它當做Linux來用吧,ls,mkdir,cp……
還有一個問題需要重點說明,那就是在程式中修改檔案的訪問許可權,先看下面的程式碼:
/* Check access permission */
if (!device.canRead() || !device.canWrite()) {
try {
/* Missing read/write permission, trying to chmod the file */
Process su;
su = Runtime.getRuntime().exec("/system/bin/su");
String cmd = "chmod 666 " + device.getAbsolutePath() + "\n"
+ "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0) || !device.canRead()
|| !device.canWrite()) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
throw new SecurityException();
}
}
其中的device為File類的物件。注意,此操作是不提倡的,因為修改了檔案的許可權後,可能導致其他本來沒有訪問許可權的應用訪問甚至修改此檔案,導致錯誤。
留一個問題共探討:在Android應用中,如果一個AppA需要訪問另一個AppB的資料庫檔案(SQLite檔案,路徑為/data/data/AppB/databases/xxx.db),AppA的路徑為/data/data/AppA,此時應該怎麼辦呢?能訪問到嗎?通過修改許可權能實現嗎?