brave-sailor https://www.cnblogs.com/Free-Thinker/p/11937531.html
_奇點 https://www.cnblogs.com/qi-dian/p/6132694.html
一、Android 應用常用存儲路徑
1.1、常用路徑
- /data/data/包名/
- /sdcard/Android/data/包名/
- /sdcard/xxx
前兩個是應用內部存儲, 會隨着app的卸載而自動刪除, sdcard中其他的文件夾不會自動刪除, 除非用戶手動刪除, 否則會一直存在, 換句話說就是垃圾.
Google官方建議把數據存儲在 /sdcard/Android/data/包名/ 下.
1.2、路徑獲取方法
前兩個應用內部存儲通過 Context 來獲取, 第三個作為外部存儲是通過 Environment 類來獲取. 注釋為返回值.
1 a、/data/data/包名/ 2 context.getFilesDir(); // /data/data/包名/files 3 context.getCacheDir(); // /data/data/包名/cache 4 b、/sdcard/Android/data/包名/ 5 context.getExternalFilesDir(); // /sdcard/Android/data/包名/files 6 context.getExternalCacheDir(); // /sdcard/Android/data/包名/cache 7 c、/sdcard/xxx 8 Environment.getExternalStorageDirectory(); //內置sdcard
注意, 根據源碼文檔中說明, 獲取外部存儲時, 有可能會因為各種問題導致獲取失敗, 建議先使用 getExternalStorageState 來判斷外部存儲狀態, 如果已掛載的話再存儲.
二、Android應用私有存儲文件的寫入與讀取
使用文件I/O 方法可以直接往手機中存儲數據,默認情況下這些文件不可以被其他的應用程序訪問。Android平台支持 java平台下的 文件I/O操作, 主要使用FileInputStream 和 FileOutputStream 這兩個類來實現文件的存儲與讀取。獲取這兩個類對象的方式有兩種。
2.1、第一種方式就是像Java平台下的實現方式一樣通過構造器直接創建,如果需要向打開的文件末尾寫入數據,可以通過使用構造器FileOutputStream(File file, boolean append)將 append設置為true來實現。不過需要注意的是采用這種方式獲得FileOutputStream 對象時如果文件不存在或不可寫入時,會拋出 FileNotFoundException 異常。
2.2、第二種獲取 FileInputStream 和 FileOutputStream 對象的方式是調用 Context.openFileInput 和 Context.openFileOutput兩個方法來創建。除了這兩個方法外,Context對象還提供了其他幾個用於對文件操作的方法,如下所示
在使用openFileOutput方法打開文件以寫入數據時,需要指定打開模式。默認為零,即MODE_PRIVATE。
2.3、允許讀寫權限:
openFileOutput(“gatsby.txt”, Context.MODE_WORLD_READABLE + Context.MODE_WORLD_WRITEABLE);
2.4、mode
模式 |
含義 |
MODE_PRIVATE |
默認模式,文件只可以被調用 |
MODE_ APPEND |
如果文件已存在就向該文件的末尾繼續寫入數據。而不是覆蓋原來的數據 |
MODE_WORLD_ READABLE |
賦予所有的應用程序對該文件讀的權限 |
MODE_WORLD_WRITEABLE |
賦予所有的應用程序對該文件寫的權限 |
三、WriteFile.apk
3.1、功能:實現新建文件、文件存儲讀寫
3.2、activiry_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 7 <EditText 8 android:id="@+id/FileName" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:hint="輸入文件名" 12 android:padding="10dp" /> 13 14 <EditText 15 android:id="@+id/FileContent" 16 android:layout_width="match_parent" 17 android:layout_height="wrap_content" 18 android:hint="輸入文件內容" 19 android:padding="10dp" /> 20 21 <LinearLayout 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" 24 android:orientation="horizontal"> 25 26 <Button 27 android:id="@+id/save" 28 android:layout_width="0dp" 29 android:layout_height="wrap_content" 30 android:layout_weight="1" 31 android:onClick="save" 32 android:text="路徑一保存" /> 33 34 <Button 35 android:id="@+id/read" 36 android:layout_width="0dp" 37 android:layout_height="wrap_content" 38 android:layout_weight="1" 39 android:onClick="read" 40 android:text="路徑一讀取" /> 41 </LinearLayout> 42 43 <TextView 44 android:id="@+id/tv1" 45 android:layout_width="match_parent" 46 android:layout_height="wrap_content" 47 android:padding="10dp" 48 android:text="文件內容" /> 49 50 51 </LinearLayout>
3.3、MainActivity.java
1 package com.gatsby.writefile; 2 3 import android.os.Bundle; 4 import android.os.Environment; 5 import android.util.Log; 6 import android.view.View; 7 import android.widget.EditText; 8 import android.widget.TextView; 9 import android.widget.Toast; 10 11 import androidx.appcompat.app.AppCompatActivity; 12 13 import java.io.ByteArrayOutputStream; 14 import java.io.File; 15 import java.io.FileInputStream; 16 import java.io.FileNotFoundException; 17 import java.io.FileOutputStream; 18 import java.io.IOException; 19 20 public class MainActivity extends AppCompatActivity { 21 22 private EditText mFilename; 23 private EditText mFileContent; 24 private TextView tv; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_main); 30 31 mFilename = findViewById(R.id.FileName); 32 mFileContent = findViewById(R.id.FileContent); 33 tv = findViewById(R.id.tv1); 34 } 35 36 public void save(View view) { 37 // 如果手機插入了SD卡,而且應用程序具有訪問SD的權限 38 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //sd卡處於掛載狀態 39 String fileName = mFilename.getText().toString(); 40 //獲取要寫入的文件目錄 storage/sdcard/Android/data/包名/files/xxx 41 File externalFilesDir = this.getExternalFilesDir(null); 42 String externalFilesDirPath = externalFilesDir.getPath(); 43 Log.d("gatsby", "externalFilesDirPath->" + externalFilesDirPath); 44 // externalFilesDirPath->/mnt/internal_sd/Android/data/com.gatsby.writefile/files 45 //創建指定目錄下的文件 46 File file = new File(externalFilesDir, fileName); 47 //開始寫文件 48 FileOutputStream fos = null; 49 try { 50 fos = new FileOutputStream(file); 51 //獲取要寫出的文件內容 52 String content = mFileContent.getText().toString(); 53 fos.write(content.getBytes("UTF-8")); 54 Toast.makeText(this, "文件保存成功", Toast.LENGTH_LONG).show(); 55 } catch (IOException e) { 56 e.printStackTrace(); 57 } finally { 58 if (fos != null) { 59 try { 60 fos.close(); 61 } catch (IOException e) { 62 e.printStackTrace(); 63 } 64 } 65 } 66 } else { 67 Toast.makeText(this, "找不到指定的SD卡", Toast.LENGTH_SHORT).show(); 68 } 69 } 70 71 public void read(View view) { 72 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 73 Log.d("gatsby", "read view!"); 74 String fileName = mFilename.getText().toString(); 75 File externalFilesDir = this.getExternalFilesDir(null); 76 File file = new File(externalFilesDir, fileName); 77 if (file.exists()) { 78 Log.d("gatsby", "file.exists!!!"); 79 FileInputStream fis; 80 try { 81 fis = new FileInputStream(file); 82 //從輸入流中讀取內容 83 String content = readStringFromInputStream(fis); 84 Log.d("gatsby", "content->" + content); 85 tv.setText("" + content); 86 mFileContent.setText("" + content); 87 } catch (FileNotFoundException e) { 88 e.printStackTrace(); 89 } 90 } else { 91 Toast.makeText(this, "該文件不存在", Toast.LENGTH_SHORT).show(); 92 } 93 } 94 } 95 96 private String readStringFromInputStream(FileInputStream fis) { 97 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 98 byte[] buffer = new byte[1024]; 99 int len; 100 try { 101 while ((len = fis.read(buffer)) != -1) { 102 baos.write(buffer, 0, len); 103 } 104 } catch (IOException e) { 105 e.printStackTrace(); 106 } 107 return baos.toString(); 108 } 109 110 }
四、 PreferctWriteFile.apk
4.1、存儲文件內容可以被其他程序讀取
1 package com.gatsby.preferctwritefile; 2 3 import android.content.Context; 4 import android.os.Bundle; 5 import android.os.Environment; 6 import android.widget.Toast; 7 8 import androidx.appcompat.app.AppCompatActivity; 9 10 import java.io.FileOutputStream; 11 import java.io.IOException; 12 13 public class WriteActivity extends AppCompatActivity { 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_main); 19 20 write(); 21 } 22 23 public void write() { 24 // 如果手機插入了SD卡,而且應用程序具有訪問SD的權限 25 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //sd卡處於掛載狀態 26 String fileName = "Ed.txt"; 27 FileOutputStream fos = null; 28 try { 29 fos = openFileOutput(fileName, Context.MODE_WORLD_READABLE); 30 //獲取要寫出的文件內容 31 String content = "Ed Sheeran,shape of you"; 32 fos.write(content.getBytes("UTF-8")); 33 Toast.makeText(this, "文件保存成功", Toast.LENGTH_LONG).show(); 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } finally { 37 if (fos != null) { 38 try { 39 fos.close(); 40 } catch (IOException e) { 41 e.printStackTrace(); 42 } 43 } 44 } 45 } else { 46 Toast.makeText(this, "找不到指定的SD卡", Toast.LENGTH_SHORT).show(); 47 } 48 } 49 50 }
五、RedFile.apk
1 package com.gatsby.readpath; 2 3 import android.os.Bundle; 4 import android.os.Environment; 5 import android.util.Log; 6 import android.widget.Toast; 7 8 import androidx.appcompat.app.AppCompatActivity; 9 10 import java.io.ByteArrayOutputStream; 11 import java.io.File; 12 import java.io.FileInputStream; 13 import java.io.FileNotFoundException; 14 import java.io.IOException; 15 16 public class RedActivity extends AppCompatActivity { 17 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 red(); 23 } 24 25 public void red() { 26 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 27 File file = new File("/data/data/com.gatsby.preferctwritefile/files/Ed.txt"); 28 if (file.exists()) { 29 Log.d("gatsby", "file.exists!!!"); 30 FileInputStream fis; 31 try { 32 fis = new FileInputStream(file); 33 //從輸入流中讀取內容 34 String content = readStringFromInputStream(fis); 35 Log.d("gatsby", "content->" + content); 36 } catch (FileNotFoundException e) { 37 e.printStackTrace(); 38 } 39 } else { 40 Toast.makeText(this, "該文件不存在", Toast.LENGTH_SHORT).show(); 41 } 42 } 43 } 44 45 private String readStringFromInputStream(FileInputStream fis) { 46 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 47 byte[] buffer = new byte[1024]; 48 int len; 49 try { 50 while ((len = fis.read(buffer)) != -1) { 51 baos.write(buffer, 0, len); 52 } 53 } catch (IOException e) { 54 e.printStackTrace(); 55 } 56 return baos.toString(); 57 } 58 59 }