介紹改文件目錄的目的是為下一次的熱修復文章二準備茧球,一般我們在線上修復bug的時候或多或少都是把.dex文件下載下來去替換原來在app的.dex文件。在app啟動的時候星持,會優(yōu)先啟動下載下來的.dex文件從而達到熱修復效果
轉至:https://blog.csdn.net/suyimin2010/article/details/81278523
先簡要介紹一下Android系統(tǒng)的文件系統(tǒng)吧抢埋,本文基于原生Android M系統(tǒng):
我們都知道Android系統(tǒng)內核就是個Linux、所以我們的文件系統(tǒng)與Linux也是基本一致的督暂,最頂部的目錄是 “/” 接下來就是 一些文件或者文件夾揪垄,如下圖:
/
├── acct
│ └── uid
│ ├── cpuacct.stat
│ └── ...
├── cache
│ ├── backup
│ │ ├── cpuacct.stat
│ │ └── ...
│ ├── lost+found
│ │ └── ...
│ ├── cpuacct.stat
│ │ └── ...
│ └── recovery
│ └── ...
│
├── ...
├── storage
│ ├── emulated
│ │ ├── 0
│ │ │ ├── Alarms
│ │ │ ├── Android
│ │ │ ├── backups
│ │ │ ├── DCIM
│ │ │ └── ...
│ │ │
│ │ └── obb
│ │
│ └── self
│ └── primary
│ ├── Alarms
│ └── ...
├── system
│
一:當然上面的有一些目錄是系統(tǒng)級的,也就是用戶是沒有權限查看的(手機有root權限的話你就可以訪問所有的目錄了)损痰。這里我們說一說在平常開發(fā)中經常使用到的目錄福侈,其他的有需要可以去了解一下。
-
應用程序的私有目錄卢未,用戶無法查看肪凛,app一安裝系統(tǒng)會自動創(chuàng)建 app一卸載系統(tǒng)也會立即刪除
/data/data/packageName/
-
用戶可以操作的文件目錄
/storage/emulated/0/
二:Android 為我們提供了一系列API來獲取我們需要的存儲目錄,如下:
- Environment.getExternalStorageDirectory().getPath();
- /storage/emulated/0
- getExternalCacheDir().getPath();
- /storage/emulated/0/Android/data/com.azhon.androiddir/cache
- getCacheDir().getPath();
- /data/user/0/com.azhon.androiddir/cache
- getFilesDir().getPath();
- /data/user/0/com.azhon.androiddir/files
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
- /storage/emulated/0/Music
- type 還可以取不同的值…
/* * @param type The type of storage directory to return. Should be one of * {@link #DIRECTORY_MUSIC}, {@link #DIRECTORY_PODCASTS}, * {@link #DIRECTORY_RINGTONES}, {@link #DIRECTORY_ALARMS}, * {@link #DIRECTORY_NOTIFICATIONS}, {@link #DIRECTORY_PICTURES}, * {@link #DIRECTORY_MOVIES}, {@link #DIRECTORY_DOWNLOADS}, * {@link #DIRECTORY_DCIM}, or {@link #DIRECTORY_DOCUMENTS}. May not be null. * @return Returns the File path for the directory. Note that this directory * may not yet exist, so you must make sure it exists before using * it such as with {@link File#mkdirs File.mkdirs()}. */ public static File getExternalStoragePublicDirectory(String type) { throwIfUserRequired(); return sCurrentUser.buildExternalStoragePublicDirs(type)[0]; }
三:在這里一直沒有找到怎么獲取/data/data/packageName/
目錄辽社,網上大部分都說是用getFilesDir()
然而我獲取到的路徑在上面已經給出了伟墙,完全不一樣。那我們要怎么獲取那個路徑呢滴铅?答案當然是直接寫嘍(反正是固定的)
- 緩存目錄
- /data/data/packageName/cache
- 數(shù)據(jù)庫目錄
- /data/data/packageName/databases
- 文件存儲目錄
- /data/data/packageName/files
- SharedPreferences文件存儲目錄
- /data/data/packageName/shared_prefs
……
四:接下來就是本文的重點了戳葵,我們都知道往手機上寫入一個文件需要 [存儲空間] 權限,在Android M之后 還需要動態(tài)申請權限汉匙。那么重點來了拱烁,當我們往App的緩存目錄中寫入一個文件 也就是/storage/emulated/0/Android/data/com.azhon.androiddir/cache
目錄它是不需要聲明權限的
對的 你沒看錯是不需要權限的下面我們來試下:
public void writeToCache(View view) { String externalCacheDir = getExternalCacheDir().getPath(); File file = new File(externalCacheDir, "test.txt"); try { FileOutputStream stream = new FileOutputStream(file); for (int i = 0; i < 66; i++) { stream.write("Hello world!\n".getBytes()); } stream.flush(); stream.close(); Toast.makeText(this, "寫入成功!", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); }}
前往文件管理器查看一下噩翠,是存在的戏自。
這里需要注意的是:這個目錄用戶是可以訪問到的所以這個里的文件是有可能會被用戶刪除的,所以在用的時候得考慮好伤锚;如果你想不被清除那么就需要保存到
/data/data/packageName/
下了擅笔。-
當app被卸載后這個文件夾也會被系統(tǒng)自動刪除
往
/data/data/packageName/
目錄下寫入一個文件,也是不需要權限的屯援。
public void writeToData(View view) { File dir = new File("/data/data/" + getPackageName() + "/files"); if (!dir.exists()) { dir.mkdirs(); } File file = new File(dir.getPath(), "test.txt"); try { FileOutputStream stream = new FileOutputStream(file); for (int i = 0; i < 66; i++) { stream.write("Hello Android!\n".getBytes()); } stream.flush(); stream.close(); Toast.makeText(this, "寫入成功猛们!", Toast.LENGTH_SHORT).show(); } catch (Exception e) { e.printStackTrace(); }}
五:在系統(tǒng)設置——應用——對應的app——存儲空間,這里可以看到我們app所占用的磁盤空間 和清理空間
這里的清除緩存按鈕對應的就是清除我們
getExternalCacheDir().getPath()
目錄下的所有文件清除數(shù)據(jù) 就是清除我們
/data/data/packageName/
目錄下的所有文件狞洋,同時也會清空getExternalCacheDir().getPath()
目錄下的所有文件-
所以我們app內經常寫到的一個清除緩存功能弯淘,現(xiàn)在就知道要怎么寫了:
public void clearCache(View view) { File externalCacheDir = getExternalCacheDir(); deleteDirFile(externalCacheDir); Toast.makeText(this, "清除緩存成功!", Toast.LENGTH_SHORT).show();}/*** 刪除指定目錄下文件及目錄*/public static void deleteDirFile(File file) { if (file.isDirectory()) { // 如果下面還有文件 File[] files = file.listFiles(); for (File f : files) { deleteDirFile(new File(f.getPath())); } } if (file.isDirectory()) { // 目錄 if (file.listFiles().length == 0) { // 目錄下沒有文件或者目錄吉懊,刪除 file.delete(); } } else { // 如果是文件耳胎,刪除 file.delete(); }}
而不是寫個這樣的清除緩存
public void clearCache(View view) { try { Thread.sleep(666); } catch (InterruptedException e) { e.printStackTrace(); } Toast.makeText(this, "清除緩存成功惯吕!", Toast.LENGTH_SHORT).show(); }}
六:總結 當我們使用到文件存儲時如:app版本更新的時候apk存放的目錄就可以使用緩存目錄了,這樣不需要權限也可以寫入怕午,開發(fā)省心废登、用戶也方便