preface

In this article, we will analyze the knowledge related to Android storage, and also lay the foundation for Android 10.0 11 storage adaptation. Through this article, you will learn:

1. Storage division 2. Internal storage 3. External storage 4

1. Storage division

The Android 4.4 before

Prior to Android 4.4, due to limited hardware development, the phone’s own storage space was limited, and it needed an external SD card to expand the storage space.

As shown above, the phone’s own storage space, called body storage, was used as internal storage prior to Android 4.4. Of course, internal storage space is usually insufficient, so you need to insert an external SD card to expand the storage space, which is considered external storage.

After the Android 4.4

After Android 4.4 (inclusive), the phone’s body storage has expanded:

As shown above, the fuselage storage is divided into two parts:

Internal storage 2. External storage

Of course, you can still insert an SD card to expand the storage space, which is called extended external storage. Only now the body storage is relatively large, rarely inserted SD card. Next, we will analyze the specific storage solution based on the storage partition after Android 4.4.

2. Internal storage

location

Think back to your usual persistence scheme:

1, SharedPreferences—-> suitable for storing small files 2, database —-> store large files with complex structure

These files are stored in internal storage by default. In the root directory “/” said, internal storage for each application package name according to its respective divides the directory, assuming that the App package called: com. Fish. Myapplication the files in the internal storage directory is: / data/user / 0 / com. Fish. Myapplication /

The first “/” represents the root directory, and each subsequent “/” represents the directory separator. “0” indicates the first user. If multiple users are added, corresponding user directories will be generated:

As shown in the figure above, two new users are added, and the generated directories are “11” and “12” respectively. Currently, multi-user is rarely enabled. Adb shell generally does not have permission to view the /data directory. To view the internal storage, you typically select the target Device to view through the Android Studio sidebar Device File Explorer.






/data/data/com.fish.myapplication/

/ data/user / 0 / com. Fish. Myapplication/will transfer value to/data/data/com. Fish. Myapplication/directory. The internal storage space of each App is only accessible to you (unless you have higher permissions, such as root). After the App is uninstalled, the directory will also be deleted.

Store content

Besides SharedPreferences and database files, what other files are stored in the internal storage? For convenience, only those in the /data/data/ directory are viewed.

There were only two empty directories to start with. After writing SharedPreferences, creating databases, writing files, etc., several new directories are added:

Briefly introduce the functions of the above directories:

Code_cache –> store the cache generated by code optimization during runtime. Databases –> store database files. Files –> Store general files 5, shared_prefs – > hold SharedPreferences file 6, lib – > store App dependent so library is soft links, pointing to a subdirectory/data/App /

access

Now that you know where all kinds of files are stored, how do you read and write them? We know that in the Java world, there are two ways to manipulate files:

Character streams and byte streams

Take the byte stream as an example, a simple read write file Demo:

Private void writeFile(String filePath) {if (textutils.isEmpty (filePath)) return; try { File file = new File(filePath); FileOutputStream fileOutputStream = new FileOutputStream(file); BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream); String writeContent = "hello world\n"; bos.write(writeContent.getBytes()); bos.flush(); bos.close(); } Catch (Exception e) {}} private void readFile(String filePath) {if (Textutils.isEmpty (filePath)) return; try { File file = new File(filePath); FileInputStream fileInputStream = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fileInputStream); byte[] readContent = new byte[1024]; int readLen = 0; while (readLen ! = -1) { readLen = bis.read(readContent, 0, readContent.length); if (readLen > 0) { String content = new String(readContent); Log.d("test", "read content:" + content.substring(0, readLen)); } } fileInputStream.close(); } catch (Exception e) { } }Copy the code

As you can see, through the FileInputStream/FileOutputStream constructor incoming File object File reading and writing can be realized, and the structure of the File object depends on the File storage path, so the emphasis is on how to access the File path. 1. Read and write files in the files directory

#Context.java
public abstract File getFilesDir();
Copy the code

Usage:

Private String getFilePath(Context Context) {// Obtain files root directory File fileDir = context.getFilesDir(); MyFile = new File(fileDir, "myFile"); return myFile.getAbsolutePath(); }Copy the code

The result of context.getfilesdir () returns the files directory:

/data/user/0/com.fish.myapplication/files/

After getting the File object of the corresponding File, the corresponding input and output stream can be constructed to achieve the read and write of the File. You can see that the process is simple but a bit boring, so Google to encapsulate these steps, return the corresponding files directly FileOutputStream/FileInputStream:

#Context.java
    public abstract FileInputStream openFileInput(String name)
        throws FileNotFoundException;

    public abstract FileOutputStream openFileOutput(String name, @FileMode int mode)
        throws FileNotFoundException;
Copy the code

Name indicates the file name and mode indicates the access permission.

2. Reading and writing files from cache is similar to reading files:

#Context.java
public abstract File getCacheDir();
Copy the code

Context.getcachedir () returns the cache directory:

/data/user/0/com.fish.myapplication/cache/

SharedPreferences provides a simple and fast data persistence scheme.

private void testSP(String fileName, String key, String value) { if (TextUtils.isEmpty(fileName) || TextUtils.isEmpty(key) || TextUtils.isEmpty(value)) return; SP = getSharedPreferences(fileName, MODE_PRIVATE); // write SP sp.edit().putString(key, value).commit(); SP String myValue = sp.getString(key, ""); }Copy the code

It also uses input and output streams internally, taking writing SP files as an example:

#SharedPreferencesImpl.java private void writeToFile(MemoryCommitResult mcr, boolean isFromSyncCommit) { ... FileOutputStream STR = createFileOutputStream(mFile); XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str); FileUtils.sync(str); str.close(); . }Copy the code

Mysql > create database;

MyDatabaseHelper myDatabaseHelper = new MyDatabaseHelper(v.getContext(), "myDB", null, 10);
Copy the code

MyDB is the database file name. Open the corresponding table of the database, you can read and write data. Get database file path:

#Context.java
Context.public abstract File getDatabasePath(String name);
Copy the code

The results are as follows:

/data/user/0/com.fish.myapplication/databases/myDB

5. Read and write files in the code_cache directory

#Context.java API>=21
public abstract File getCodeCacheDir();
Copy the code

The results are as follows:

/data/user/0/com.fish.myapplication/code_cache/

Above is respectively lists various subdirectories/file access, if you want to get: / data/user / 0 / com. Fish. Myapplication /, by:

#Context.java
public abstract File getDataDir();
Copy the code

This method requires API>=24.

3. External storage

External storage is divided into two parts: built-in external storage and extended external storage (external SD card)

A. Built-in external storage

location

The root directory for storage is: “/”. Note the following directories in the root directory:

/data/

/sdcard/

/storage/

The /data/ directory has been analyzed previously.

/sdcard/ is a soft link to /storage/self/primary and /storage/ has several directories:

/sdcard/ /self/primary/ /storage/emulated/0/

Store content

As you can see above, the subdirectories under the /sdcard/ directory all look familiar. These subdirectories are divided into three parts:

Part one: Shared storage Space

That’s what all apps share, like albums, music, ringtones, documents, etc. The shared storage space is divided into two parts by file type: 1. Media files

  • DCIM/ and Pictures/–> Store Pictures
  • DCIM/, Movies/ and Pictures–> Store videos
  • Alarms/, Audiobooks/, Music/, Notifications/, Podcasts/, and Ringtones/–> Store audio files
  • Download/–> Downloaded files

2. Documents and other documents

  • Documents–> Store files such as.pdf

Part TWO: Private directories outside the App

  • Android/data/– > External private directory for storing each App
  • Android/data/xx——>xx indicates the package name of the application.
  • Such as: / sdcard/Android/data/com. Fish. Myapplication

Part III: Other contents

For example, directories created by each App under /sdcard/, such as alipy/ created by Alipay, com.sina. Weibo/created by Weibo, com.tencent. Mobileqq/created by qq, etc.

access

Similar to accessing internal storage files, external storage can also access files by constructing input and output streams.

Read/write the shared storage space

Videos, pictures and so on May be scattered in different directories. If you want to obtain the address of all pictures, you have to search through different directories, which is obviously inefficient. Android stores videos, pictures and other information in the database. Whenever an App wants to access these shared media files, it only needs to look up the corresponding table in the database, read qualified rows and find out the file path of each media. You can use the ContentProvider to query the media of the shared storage space.

Accessing media files The following uses querying images as an example:

private void getImagePath(Context context) { ContentResolver contentResolver = context.getContentResolver(); Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null); while(cursor.moveToNext()) { String imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)); }}Copy the code

Query the address of the picture, of course, you can show the picture.

Storage Access Framework SAF: View. PDF files as an example.

private void startSAF() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("application/pdf"); startActivityForResult(intent, 100); } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 100) { Uri uri = data.getData(); }}Copy the code

SAF calls the system selector, receives the result in onActivityResult(xx), and reads and writes the Uri.

Read and write private directories outside the App

I didn’t have a package name for my App at first.

Private void testAppDir Context (Context) {/ / four basic methods File, fileDir, = Context. GetExternalFilesDir (null); //API>=19 File[] fileList = context.getExternalFilesDirs(null); File cacheDir = context.getExternalCacheDir(); //API>=19 File[] cacheList = context.getExternalCacheDirs(); / / specified directories, subdirectories to automatically generate the corresponding File fileDir2 = context. GetExternalFilesDir (Environment. DIRECTORY_DCIM); }Copy the code

Look at the directory tree again:

2. Both will be removed when the App is uninstalled.

Reading and writing to other directories

Once you get to the root directory, you can traverse for other subdirectories/files.

    private void testOtherDir(Context context) {
        File rootDir = Environment.getExternalStorageDirectory();
    }
Copy the code

The returned rootDir path is /storage/emulated/0/.

B. Expansion of external storage (external SD card)

Storage location

After inserting the SD card into the device, look at its directory: /sdcard/ still pointing to /storage/self/primary, continue to look at /storage/:

Store content

Depends on what’s on the SD card.

access

Remember the way to get external storage-app private directory above?

File[] fileList = context.getExternalFilesDirs(null);
Copy the code

Returns an array of File objects, stored in an array when there are multiple external stores.

4. Easy to confuse point description

The above respectively describes internal storage, own external storage, extended external storage, etc., which are as follows:

One of the things that can get confusing is the naming style of the App’s private directories in internal storage and external storage.

Difference:

/ data/data/com. Fish. Myapplication/located in internal storage, generally used for smaller storage capacity, illicit close sex strong file. The/sdcard/Android/data/com. Fish. Myapplication/located on the external storage, as a private directory, App is commonly used in storage capacity larger files, even if delete the function does not affect the normal App.

Similarities:

1. It is exclusive to the App, and the App itself does not need any permission to access the two. 2. Both will be deleted after App uninstallation. 3. Files added to both directories will eventually be counted in Settings -> Storage and Cache.

Also, common “store and cache” items in Settings:

When clicking “Clear Cache “:

Internal storage/data/data/com. Fish. Myapplication/cache / > / data/data/com. Fish. Myapplication code_cache/directory will be empty External storage/sdcard/Android/data/com. Fish. Myapplication/cache/will be empty

When clicking “Clear Storage “:

Internal storage/data/data/com. Fish. In addition to the lib/myapplication /, the rest of the subdirectories are deleted External storage/sdcard/Android/data/com. Fish. Myapplication/empty note: App\color{Red} this function is used with caution, because it will delete the user database, SP file, etc., which is the same as the reset App

Next we’ll look at Android 10.0 11 storage adaptation. This article is based on Android 10.0.

If you like, please like, pay attention to your encouragement is my motivation to move forward

Continue to update, with me step by step system, in-depth study of Android