1, File read and write permissions
(1) Authority
Read and write permission is required when reading and writing files in external storage;
Read and write files in "internal storage" without "read and write permission
- Write file to external storage [write]
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- Read file from external storage [read]
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
(2) Remind
Starting from API level 19, when reading the files in the external storage path obtained by the functions getExternalFilesDir and getExternalCacheDir, the read-write permission is no longer required
2, Difference between internal storage and external storage
The File object is suitable for reading or writing large amounts of data in the order from start to end without skipping.
For example, it is suitable for picture files or any content exchanged over the network
(1) Characteristics of internal storage
- Always available
- Only this app can access this saved file
- When the user uninstalls the application, the system will remove all the files of the application from the internal storage
Applicable scenario: when ensuring that users or other applications cannot access your files, internal storage is the best choice
(2) Characteristics of external storage
- It is not always available because users can load external storage in the form of USB storage device and remove it from the device in some cases (but most smartphones no longer support the form of removable SD card)
- Globally readable, so the files saved here may be read out of your control
- When the user uninstalls your application, the system will remove your application's files from this directory only when you save your application's files in the directory through getExternalFilesDir()
Applicable scenario: external storage is the best location for files that do not require access restrictions and that you want to share with other applications or allow users to access using the computer
(3) Hint
Tip: Although the application is installed in the internal storage by default, you can specify the android:installLocation attribute in your manifest file so that your application can be installed in the external storage.
When apks are very large and their external storage space is larger than their internal storage, users prefer this option.
When the file does not want to be accessed by other applications, you can choose internal storage;
When you want to save files for a long time, you can choose external storage (but there is also a private location in the external storage, that is, the files stored in this path will be automatically removed with apk unloading)
3, Access corresponding functions of external storage
(1) Prior work: test whether the file is allowed to read and write [for external storage]
It's best to test the state of external storage before file operation. Use the function getExternalStorageState. When the returned result is MEDIA_MOUNTED indicates that you can continue reading and writing the following files
/* Checks if external storage is available for read and write */ /* Check whether external memory is available for reading and writing */ public boolean isExternalStorageWritable(){ String state = Environment.getExternalStorageState(); if(Environment.MEDIA_MOUNTED.equals(state)){ return true; } Log.e(TAG, "isExternalStorageWritable: " + state); return false; }
As mentioned above, external storage is also divided into two parts. One is a complete public area, and the files in it need to be explicitly removed; The other is a relatively private area. Although it can also be accessed by other applications under this path, the files under this path will be automatically removed with the unloading of the application
(2) Access to public areas
-Direct return to external storage home directory
Environment.getExternalStorageDirectory
code:
String mainDir = Environment.getExternalStorageDirectory().getAbsolutePath();
result:
/storage/emulated/0
-Access private directory
Android places some files of the same file type in the same directory in external storage, such as pictures, videos, documents, music, etc.
If you want a private directory, you can use the function environment getExternalStoragePublicDirectory
The standard storage directory is as follows
public static final String[] STANDARD_DIRECTORIES = { DIRECTORY_MUSIC, //Catalogue_ music DIRECTORY_PODCASTS,//Catalogue_ Podcast Blog Highlights broadcast DIRECTORY_RINGTONES,//Catalogue_ Incoming ringtone mobile ringtone random ringtone DIRECTORY_ALARMS,//Catalogue_ Warning alarm clock DIRECTORY_NOTIFICATIONS,//Catalogue_ notice DIRECTORY_PICTURES,//Catalogue_ Related pictures DIRECTORY_MOVIES,//Catalogue_ film DIRECTORY_DOWNLOADS,//Catalogue_ download DIRECTORY_DCIM,//Catalogue_ Data center infrastructure management DIRECTORY_DOCUMENTS//Catalogue_ Documents and certificates };
code:
String dcimDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) .getAbsolutePath(); String pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoultPath();
result:
/storage/emulated/0/Pictures /storage/emulated/0/DCIM
-Access private areas
Use the function getExternalFilesDir(String)
- If the parameter is empty, it means to return the "root" directory of the private directory applied on the external storage
String fileDir = getExternalFilesDir(null).getAbsolutePath();
result:
/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files
- Create standard catalog
String movieDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES).getAbsolutePath(); String documentDir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath();
result:
/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Movies /storage/emulated/0/Android/data/com.penglaoxi.filedemo/Documents
4, Read and write files to external storage
Using Java IO class is enough
(1) [write] string and picture to external storage
-Write string
private void writeStringToFile(String str){ //Judge whether external storage allows write operation if(!isExternalStorageWritable()){ //If not, exit the method return; } //If a write operation is allowed, do the following File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); //Log output path Log.e("TAG","writeStringToFile: dir = " + dir.getAbsolutePath()); //If the target does not exist if(!dir.exists()){ //Create multi-level directory dir.mkdirs(); } //Create a txt file to save the string, "str" is the custom file name File file = new File(dir,"str.txt"); //If the file exists if(file.exists()){ //If there is a file with the same name, delete it file.delete(); } FileOutputStream fos = null; BufferedOutputStream bos = null; try{ //create a file file.createNewFile(); //File output stream (file) fos = new FileOutputStream(file); //Buffered output stream (fos) bos = new BufferedOutputStream(fos); bos.write(str.getBytes()); //Close cache stream bos.close(); //Close input stream fos.close(); } catch (IOException e) { e.printStackTrace(); }finally{ try{ if(bos != null){ bos.close(); } if(fos != null){ fos.close(); } }catch (IOException e) { e.printStackTrace(); } } } /* Checks if external storage is available for read and write */ public boolean isExternalStorageWritable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } Log.e(TAG, "isExternalStorageWritable: " + state); return false; }
-Write picture
private void writeImageToFile(Bitmap bitmap) { //Judge whether external storage allows write operation if (!isExternalStorageWritable()) { return; } //Get external file directory File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); //Output photo path [external file directory] Log.e(TAG, "writeImageToFile: dir = " + dir.getAbsolutePath()); if(!dir.exists()){ //Create multi-level directory dir.mkdirs(); } File file = new File(dir,"penglaoxi.png") //If the file is inconsistent if(file.existe()){ //Delete target file file.delete(); } FileOutputStream fos = null; BufferedOutputStream bos = null; try{ //create a file file.createNewFile(); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); //Compressed picture bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos); //Refresh bos.flush(); bos.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bos != null) { bos.close(); } if (fos != null) { fos.close(); } } catch (IOException e) { e.printStackTrace(); } } }
The writeStringToFile(String) function is used to write the string locally, and select the local path as the document private directory in the external storage private path
/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Documents
The writeImageToFile(Bitmap) function is used to write pictures locally, and select the local path as the picture private directory in the external storage private path
/storage/emulated/0/Android/data/com.penglaoxi.filedemo/files/Pictures
Before writing, judge whether the external storage is available; Then judge whether the file directory exists, and create a new one if it does not exist; Last write file
(2) Store [read] text files and picture files externally
Read text file in external storage - readStringFromFile:
private String readStringFromFile() { //Judge whether reading operation is allowed if (!isExternalStorageWritable()) { return null; } //Get external storage directory File dir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS); Log.e(TAG,"readStringFromFile: dir = " + dir.getAbsolutePath()); if(!dir.exists()){ return null; } File file = new File(dir,"str.txt"); if(!file.exists()){ return null; } //File input stream FileInputStream fis = null; //Character stream conversion stream input stream InputStreamReader isr = null; //Buffer read input stream BufferedReader br = null; //String buffer StringBuffer sb = new StringBuffer(); try{ fis = new FileInputStream(file); isr = new InputStreamReader(fis); br = new BufferedReader(isr); String line; //String buffer write buffer stream br (read line by line) sb.append(br.readLine()); //If the string of the file is not empty while((line = br.readLine()) != null){ //Write the data of each row circularly sb.append("\n" + line); } br.close(); isr.close(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (br != null) { br.close(); } if (isr != null) { isr.close(); } if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } //Returns the read text return sb.toString(); }
Read image file in external storage - readBitmapFromFile:
private Bitmap readBitmapFromFile() { if (!isExternalStorageWritable()) { return null; } File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); Log.e(TAG, "readBitmapFromFile: dir = " + dir.getAbsolutePath()); if(!dir.existe()){ return null; } File file = new File(dir,"penglaoxi.png"); if(!file.exists()){ return null; } FileInputStream fis = null; BufferedInputStream bis = null; Bitmap bitmap = null; try{ fis = new FileInputStream(file); bis = new BufferedInputStream(fis); //Bitmap compression bitmap = BitmapFactory.decodeStream(bis); bis.close(); fis.close(); }catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (bis != null) { bis.close(); } if (fis != null) { fis.close(); } } catch (IOException e) { e.printStackTrace(); } } return bitmap; }