1. 程式人生 > >Android之File操作許可權

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,此時應該怎麼辦呢?能訪問到嗎?通過修改許可權能實現嗎?