6.1 Data Storage and Access - File Storage Read and Write
Category Android Basic Tutorial
Introduction to This Section:
>
Hey, seeing this topic, I believe some readers will ask, have you finished the Fragment from before? Well, not yet, because thinking of examples takes some time. To improve efficiency, I've decided to write the tutorial concurrently, like multithreading, which might speed up the progress of writing the tutorial. So far, I've written exactly 60 articles, which is still far from completing the introductory tutorial. As I mentioned before, I wanted to finish this set of tutorials in a month and a half, and today is already September 1st, so I need to step up the pace. Alright, that's enough chitchat. This section introduces one of the ways of Android data storage and access - file storage and read/write, of course, in addition to this method, we can also store in SharedPreferences, databases, or the Application, of course, I will talk about these later, okay, let's start this section~
1.Android File Operation Modes
>
Students who have studied Java know that we create a new file and then we can write data into it, but Android is different because Android is based on Linux. When we read and write files, we also need to add the file operation mode. The operation modes in Android are as follows:
2.Related File Operation Methods
3.Implementation of File Reading and Writing
>
File reading and writing in Android is the same as file I/O in Java, and the process is also very simple. Let's write a simple example below:
Implementation Effect Picture:
PS: This is done on the emulator because my N5 is not rooted, and I can't see the file storage directory. Below, we can open the DDMS File Explorer and see that in data/data/<package name>/file there is the file we wrote:
We can click on the response icon in the upper right corner to import the file to the computer and open it to verify the written content:
Code Implementation:
First, the layout file: main_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.filedemo1.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/nametitle" />
<EditText
android:id="@+id/editname"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/detailtitle" />
<EditText
android:id="@+id/editdetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minLines="2" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnsave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnwrite" />
<Button
android:id="@+id/btnclean"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnclean" />
</LinearLayout>
<Button
android:id="@+id/btnread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btnread" />
</LinearLayout>
Then let's write a file assistant class: FileHelper.java
/**
* Created by Jay on 2015/9/1 0001.
*/
public class FileHelper {
private Context mContext;
public FileHelper() {
}
public FileHelper(Context mContext) {
super();
this.mContext = mContext;
}
/*
* Here we define a file saving method, writing to the file, so it is an output stream
* */
public void save(String filename, String filecontent) throws Exception {
//Here we use private mode, the created file can only be accessed by this application, and it will also overwrite the original file
FileOutputStream output = mContext.openFileOutput(filename, Context.MODE_PRIVATE);
output.write(filecontent.getBytes()); //Write the String string into the output stream as a byte
Toast.makeText(getApplicationContext(), "Data written successfully", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Data writing failed", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btnread:
String detail = "";
FileHelper fHelper2 = new FileHelper(getApplicationContext());
try {
String fname = editname.getText().toString();
detail = fHelper2.read(fname);
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
break;
}
}
}
4. Read a file from the SD card
Reading process diagram :
Code example :
Running effect picture :
Similarly, open the DDMS File Explorer. On older systems, we can directly find it on mmt\sdcard, but the newer versions may require us to look for it ourselves. First, let's go to this path:
Click on sdcard, but there's nothing there, let's continue to look for it in the back at /storage/emulated/legacy:
Well, it jumped to another place, let's continue to look for it at /storage/shell/emulated/0
Sure enough, we found it, the test.txt we generated in the SD card! Export it to the computer to check the content inside:
Hehe, it turns out that reading and writing to the SD card was successful~ Next, let's take a look at how the code is written:
Code implementation:
main_activity.xml :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.jay.example.filedemo2.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please enter the file name" />
<EditText
android:id="@+id/edittitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="File name" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please enter the file content" />
<EditText
android:id="@+id/editdetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="File content" />
<Button
android:id="@+id/btnsave"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save to SD card" />
<Button
android:id="@+id/btnclean"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear" />
<Button
android:id="@+id/btnread"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Read a file from the SD card" />
</LinearLayout>
Next, let's write an SD card operation class: SDFileHelper.java
/**
* Created by Jay on 2015/9/1 0001.
*/
public class SDFileHelper {
private Context context;
public SDFileHelper() {
}
public SDFileHelper(Context context) {
super();
this.context = context;
}
// Method to write a file to the SD card
public void saveFileToSD(String filename, String filecontent) throws Exception {
// If the phone has an SD card inserted and the app has permission to read and write the SD card
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
// Here, do not use openFileOutput, that is for writing data to the phone's memory
FileOutputStream output = new FileOutputStream(filename);
output.write(filecontent.getBytes());
// Write the String as a byte stream to the output stream
output.close();
// Close the output stream
} else Toast.makeText(context, "SD card does not exist or is not readable and writable", Toast.LENGTH_SHORT).show();
}
// Method to read a file from the SD card
// Define the method to read the file:
public String readFromSD(String filename) throws IOException {
StringBuilder sb = new StringBuilder("");
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
filename = Environment.getExternalStorageDirectory().getCanonicalPath() + "/" + filename;
// Open the file input stream
btnread = (Button) findViewById(R.id.btnread);
btnsave.setOnClickListener(this);
btnclean.setOnClickListener(this);
btnread.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnclean:
editdetail.setText("");
editname.setText("");
break;
case R.id.btnsave:
String filename = editname.getText().toString();
String filedetail = editdetail.getText().toString();
SDFileHelper sdHelper = new SDFileHelper(mContext);
try
{
sdHelper.savaFileToSD(filename, filedetail);
Toast.makeText(getApplicationContext(), "Data write successful", Toast.LENGTH_SHORT).show();
}
catch(Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Data write failed", Toast.LENGTH_SHORT).show();
}
break;
case R.id.btnread:
String detail = "";
SDFileHelper sdHelper2 = new SDFileHelper(mContext);
try
{
String filename2 = editname.getText().toString();
detail = sdHelper2.readFromSD(filename2);
}
catch(IOException e){e.printStackTrace();}
Toast.makeText(getApplicationContext(), detail, Toast.LENGTH_SHORT).show();
break;
}
}
}
Don't forget to add the permissions for reading and writing to the SD card in **AndroidManifest.xml**!
<!-- Permission for creating and deleting files on the SDCard --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- Permission for writing data to the SDCard --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
---
## 5. Issues with the SD card on native emulators
>
If you are debugging on a real device, it usually works fine. For native virtual machines, there are many issues. When we previously used Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED), it may always return false, meaning the SD card does not exist. This is the main problem. Newer versions of the SDK will request a storage area for the SD card when creating an AVD.
For older versions of the SDK or other reasons, you may need to manually associate the SD card. The settings are as follows:
②Go to the path where the AVD image is located and copy the path of the sdcard.img:
③Then click
Finally, apply the following and then Run!
---
## 6. Reading files in the raw and assets folders
>
I believe everyone is familiar with these two folders. If we don't want our files to be compiled into binary files, we can put the files in these two directories. The differences between the two are as follows:
-**res/raw** : The file will be mapped to the R.java file, and you can access it directly through the resource ID. It cannot have a directory structure, meaning you cannot create folders.
-**assets** : It will not be mapped to the R.java file and is accessed through the AssetManager. It can have a directory structure, meaning you can create folders yourself.
**Reading file resources:**
**res/raw** :
InputStream is =getResources().openRawResource(R.raw.filename);
**assets** :
AssetManager am = getAssets();
InputStream is = am.open("filename");
```
Code download:
-FileDemo.zip:
-FileDemo2.zip:
Summary of this section:
>
Well, that's it for the first section on Android data storage and access - file reading and writing. If you encounter any problems while studying this article, or if you think there are some omissions, please feel free to point them out. I am very grateful, thank you~
-1.0.1 Latest Android Basic Tutorial Catalog for 2015
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Setup
-1.2.1 Developing Android APP with Eclipse + ADT + SDK
-1.2.2 Developing Android APP with Android Studio
-1.3 Solving SDK Update Issues
-1.4 Genymotion Emulator Installation
-1.5.1 Git Tutorial on Basic Operations of Local Repositories
-1.5.2 Git on Using GitHub to Set Up a Remote Repository
-[1.6 How to Play with 9 (Nine Sister) Images](android-tutorial
2.5.4 Basic Usage of AutoCompleteTextView (Auto-Complete Text Box)
2.5.8 Detailed Explanation of Notification (Status Bar Notification)
2.6.4 Simple Usage of DrawerLayout (Official Side-Slide Menu)
3.6 Responding to System Setting Events (Configuration Class)
4.4.2 Further Exploration of ContentProvider - Document Provider
5.2.1 In-Depth Explanation of Fragment - Implementing a Bottom Navigation Bar (Method 1)
5.2.2 In-Depth Explanation of Fragment - Implementing a Bottom Navigation Bar (Method 2)
5.2.3 In-Depth Explanation of Fragment - Implementing a Bottom Navigation Bar (Method 3)
5.2.4 In-Depth Explanation of Fragment - Bottom Navigation Bar + ViewPager for Page Swiping
[5.2.5 In-Depth Explanation of Fragment - A Simple Implementation of a News
8.3.5 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 2)
8.3.6 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 3)
8.3.7 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 4)
8.3.8 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 5)
8.3.14 Paint API - Several Enumeration/Constant Values and ShadowLayer Shadow Effect
8.3.17 Canvas API Detailed Explanation (Part 2) - Clipping Method Collection
8.3.18 Canvas API Detailed Explanation (Part 3) - Matrix and drawBitmapMesh
8.4.3 Android Animation Collection - Property Animation - First Encounter
8.4.4 Android Animation Collection - Property Animation - Another Encounter
11.0 "2015 Latest Android Basic Tutorial" Completion Celebration~
12.2 DrySister Girl Viewing App (First Edition) - 2. Parsing Backend Data
-