Android File存储(二):文件读写
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 }